From 2c8668479c654fa3e1b7caa22f1a25b48a72b00e Mon Sep 17 00:00:00 2001 From: Juan Carlos Luciani Date: Mon, 13 Nov 2006 05:20:43 +0000 Subject: [PATCH] Splitted the non-java project into client and server projects in order to be able to deliver the client component onto distributions targeting desktops without having to deliver the server components. This commit is for the resulting client project. --- CASA-auth-token/client/AUTHORS | 2 + CASA-auth-token/client/COPYING | 459 +++++++++ CASA-auth-token/client/ChangeLog | 0 CASA-auth-token/client/Makefile.am | 41 + CASA-auth-token/client/NEWS | 0 CASA-auth-token/client/README | 241 +++++ CASA-auth-token/client/TODO | 17 + CASA-auth-token/client/auth.sln | 77 ++ CASA-auth-token/client/autogen.sh | 130 +++ CASA-auth-token/client/configure.in | 285 ++++++ CASA-auth-token/client/core/Makefile.am | 37 + CASA-auth-token/client/core/README | 90 ++ CASA-auth-token/client/core/TODO | 13 + CASA-auth-token/client/core/authmech.c | 343 +++++++ CASA-auth-token/client/core/authmsg.c | 803 ++++++++++++++++ CASA-auth-token/client/core/authpolicy.c | 804 ++++++++++++++++ CASA-auth-token/client/core/cache.c | 588 ++++++++++++ CASA-auth-token/client/core/client.conf | 88 ++ CASA-auth-token/client/core/config.c | 686 ++++++++++++++ CASA-auth-token/client/core/config_if.h | 120 +++ CASA-auth-token/client/core/engine.c | 894 ++++++++++++++++++ CASA-auth-token/client/core/getpolicymsg.c | 745 +++++++++++++++ CASA-auth-token/client/core/gettokenmsg.c | 793 ++++++++++++++++ CASA-auth-token/client/core/internal.h | 437 +++++++++ CASA-auth-token/client/core/invalidcert.c | 140 +++ CASA-auth-token/client/core/linux/Makefile.am | 126 +++ CASA-auth-token/client/core/linux/platform.c | 831 ++++++++++++++++ CASA-auth-token/client/core/linux/platform.h | 130 +++ CASA-auth-token/client/core/linux/rpc.c | 566 +++++++++++ CASA-auth-token/client/core/mech_if.h | 184 ++++ .../client/core/mechanisms/Makefile.am | 37 + .../client/core/mechanisms/krb5/Makefile.am | 37 + .../client/core/mechanisms/krb5/README | 53 ++ .../client/core/mechanisms/krb5/TODO | 13 + .../client/core/mechanisms/krb5/interface.c | 207 ++++ .../client/core/mechanisms/krb5/internal.h | 92 ++ .../krb5/linux/Krb5Authenticate.conf | 12 + .../krb5/linux/Krb5Authenticate_lib64.conf | 12 + .../core/mechanisms/krb5/linux/Makefile.am | 122 +++ .../client/core/mechanisms/krb5/linux/get.c | 385 ++++++++ .../core/mechanisms/krb5/linux/platform.c | 35 + .../core/mechanisms/krb5/linux/platform.h | 90 ++ .../client/core/mechanisms/krb5/util.c | 282 ++++++ .../krb5/windows/Krb5Authenticate.conf | 12 + .../core/mechanisms/krb5/windows/Makefile.am | 69 ++ .../core/mechanisms/krb5/windows/dllsup.c | 132 +++ .../client/core/mechanisms/krb5/windows/get.c | 300 ++++++ .../core/mechanisms/krb5/windows/krb5.vcproj | 182 ++++ .../core/mechanisms/krb5/windows/krb5mech.def | 10 + .../core/mechanisms/krb5/windows/platform.c | 35 + .../core/mechanisms/krb5/windows/platform.h | 83 ++ .../client/core/mechanisms/pwd/Makefile.am | 37 + .../client/core/mechanisms/pwd/README | 50 + .../client/core/mechanisms/pwd/TODO | 13 + .../client/core/mechanisms/pwd/get.c | 352 +++++++ .../client/core/mechanisms/pwd/interface.c | 207 ++++ .../client/core/mechanisms/pwd/internal.h | 90 ++ .../core/mechanisms/pwd/linux/Makefile.am | 122 +++ .../mechanisms/pwd/linux/PwdAuthenticate.conf | 12 + .../pwd/linux/PwdAuthenticate_lib64.conf | 12 + .../core/mechanisms/pwd/linux/platform.c | 35 + .../core/mechanisms/pwd/linux/platform.h | 88 ++ .../client/core/mechanisms/pwd/util.c | 282 ++++++ .../core/mechanisms/pwd/windows/Makefile.am | 69 ++ .../pwd/windows/PwdAuthenticate.conf | 12 + .../core/mechanisms/pwd/windows/dllsup.c | 126 +++ .../core/mechanisms/pwd/windows/platform.c | 35 + .../core/mechanisms/pwd/windows/platform.h | 81 ++ .../core/mechanisms/pwd/windows/pwd.vcproj | 182 ++++ .../core/mechanisms/pwd/windows/pwmech.def | 10 + .../client/core/test/CASA_Auth.cpp | 382 ++++++++ .../client/core/test/linux/main.cpp | 171 ++++ .../client/core/test/linux/make.sh | 2 + .../client/core/test/linux/platform.h | 54 ++ .../client/core/test/windows/main.cpp | 187 ++++ .../client/core/test/windows/platform.h | 29 + .../client/core/test/windows/test.vcproj | 145 +++ CASA-auth-token/client/core/util.c | 321 +++++++ .../client/core/windows/Makefile.am | 69 ++ .../client/core/windows/authtoken.def | 11 + .../client/core/windows/client.vcproj | 224 +++++ CASA-auth-token/client/core/windows/dllsup.c | 233 +++++ .../client/core/windows/platform.c | 580 ++++++++++++ .../client/core/windows/platform.h | 103 ++ CASA-auth-token/client/core/windows/rpc.c | 799 ++++++++++++++++ .../Novell.Casa.Authtoken/AssemblyInfo.cs | 57 ++ .../Novell.Casa.Authtoken/AuthToken.snk | Bin 0 -> 596 bytes .../csharp/Novell.Casa.Authtoken/Authtoken.cs | 176 ++++ .../Novell.Casa.Client.csproj | 105 ++ .../csharp/Novell.Casa.Authtoken/WinLuid.cs | 29 + CASA-auth-token/client/csharp/README | 68 ++ CASA-auth-token/client/csharp/TODO | 15 + CASA-auth-token/client/csharp/test/App.ico | Bin 0 -> 1078 bytes .../client/csharp/test/AssemblyInfo.cs | 58 ++ CASA-auth-token/client/csharp/test/Class1.cs | 74 ++ .../client/csharp/test/TestClientAuth.csproj | 109 +++ CASA-auth-token/client/include/Makefile.am | 40 + .../client/include/casa_c_authtoken.h | 102 ++ CASA-auth-token/client/include/list_entry.h | 187 ++++ CASA-auth-token/client/include/proto.h | 70 ++ .../include/windows/casa_c_authtoken_ex.h | 109 +++ CASA-auth-token/client/package/Makefile.am | 38 + .../linux/CASA_auth_token_client.changes | 83 ++ .../linux/CASA_auth_token_native.changes | 83 ++ .../client/package/linux/Makefile.am | 67 ++ .../client/package/windows/Makefile.am | 39 + .../windows/authtokenclient_msi/Makefile.am | 69 ++ .../authtokenclient_msi.vdproj | 699 ++++++++++++++ .../windows/authtokenclient_msm/Makefile.am | 69 ++ .../authtokenclient_msm.vdproj | 647 +++++++++++++ 110 files changed, 19988 insertions(+) create mode 100644 CASA-auth-token/client/AUTHORS create mode 100644 CASA-auth-token/client/COPYING create mode 100644 CASA-auth-token/client/ChangeLog create mode 100644 CASA-auth-token/client/Makefile.am create mode 100644 CASA-auth-token/client/NEWS create mode 100644 CASA-auth-token/client/README create mode 100644 CASA-auth-token/client/TODO create mode 100644 CASA-auth-token/client/auth.sln create mode 100755 CASA-auth-token/client/autogen.sh create mode 100644 CASA-auth-token/client/configure.in create mode 100644 CASA-auth-token/client/core/Makefile.am create mode 100644 CASA-auth-token/client/core/README create mode 100644 CASA-auth-token/client/core/TODO create mode 100644 CASA-auth-token/client/core/authmech.c create mode 100644 CASA-auth-token/client/core/authmsg.c create mode 100644 CASA-auth-token/client/core/authpolicy.c create mode 100644 CASA-auth-token/client/core/cache.c create mode 100644 CASA-auth-token/client/core/client.conf create mode 100644 CASA-auth-token/client/core/config.c create mode 100644 CASA-auth-token/client/core/config_if.h create mode 100644 CASA-auth-token/client/core/engine.c create mode 100644 CASA-auth-token/client/core/getpolicymsg.c create mode 100644 CASA-auth-token/client/core/gettokenmsg.c create mode 100644 CASA-auth-token/client/core/internal.h create mode 100644 CASA-auth-token/client/core/invalidcert.c create mode 100644 CASA-auth-token/client/core/linux/Makefile.am create mode 100644 CASA-auth-token/client/core/linux/platform.c create mode 100644 CASA-auth-token/client/core/linux/platform.h create mode 100644 CASA-auth-token/client/core/linux/rpc.c create mode 100644 CASA-auth-token/client/core/mech_if.h create mode 100644 CASA-auth-token/client/core/mechanisms/Makefile.am create mode 100644 CASA-auth-token/client/core/mechanisms/krb5/Makefile.am create mode 100644 CASA-auth-token/client/core/mechanisms/krb5/README create mode 100644 CASA-auth-token/client/core/mechanisms/krb5/TODO create mode 100644 CASA-auth-token/client/core/mechanisms/krb5/interface.c create mode 100644 CASA-auth-token/client/core/mechanisms/krb5/internal.h create mode 100644 CASA-auth-token/client/core/mechanisms/krb5/linux/Krb5Authenticate.conf create mode 100644 CASA-auth-token/client/core/mechanisms/krb5/linux/Krb5Authenticate_lib64.conf create mode 100644 CASA-auth-token/client/core/mechanisms/krb5/linux/Makefile.am create mode 100644 CASA-auth-token/client/core/mechanisms/krb5/linux/get.c create mode 100644 CASA-auth-token/client/core/mechanisms/krb5/linux/platform.c create mode 100644 CASA-auth-token/client/core/mechanisms/krb5/linux/platform.h create mode 100644 CASA-auth-token/client/core/mechanisms/krb5/util.c create mode 100644 CASA-auth-token/client/core/mechanisms/krb5/windows/Krb5Authenticate.conf create mode 100644 CASA-auth-token/client/core/mechanisms/krb5/windows/Makefile.am create mode 100644 CASA-auth-token/client/core/mechanisms/krb5/windows/dllsup.c create mode 100644 CASA-auth-token/client/core/mechanisms/krb5/windows/get.c create mode 100644 CASA-auth-token/client/core/mechanisms/krb5/windows/krb5.vcproj create mode 100644 CASA-auth-token/client/core/mechanisms/krb5/windows/krb5mech.def create mode 100644 CASA-auth-token/client/core/mechanisms/krb5/windows/platform.c create mode 100644 CASA-auth-token/client/core/mechanisms/krb5/windows/platform.h create mode 100644 CASA-auth-token/client/core/mechanisms/pwd/Makefile.am create mode 100644 CASA-auth-token/client/core/mechanisms/pwd/README create mode 100644 CASA-auth-token/client/core/mechanisms/pwd/TODO create mode 100644 CASA-auth-token/client/core/mechanisms/pwd/get.c create mode 100644 CASA-auth-token/client/core/mechanisms/pwd/interface.c create mode 100644 CASA-auth-token/client/core/mechanisms/pwd/internal.h create mode 100644 CASA-auth-token/client/core/mechanisms/pwd/linux/Makefile.am create mode 100644 CASA-auth-token/client/core/mechanisms/pwd/linux/PwdAuthenticate.conf create mode 100644 CASA-auth-token/client/core/mechanisms/pwd/linux/PwdAuthenticate_lib64.conf create mode 100644 CASA-auth-token/client/core/mechanisms/pwd/linux/platform.c create mode 100644 CASA-auth-token/client/core/mechanisms/pwd/linux/platform.h create mode 100644 CASA-auth-token/client/core/mechanisms/pwd/util.c create mode 100644 CASA-auth-token/client/core/mechanisms/pwd/windows/Makefile.am create mode 100644 CASA-auth-token/client/core/mechanisms/pwd/windows/PwdAuthenticate.conf create mode 100644 CASA-auth-token/client/core/mechanisms/pwd/windows/dllsup.c create mode 100644 CASA-auth-token/client/core/mechanisms/pwd/windows/platform.c create mode 100644 CASA-auth-token/client/core/mechanisms/pwd/windows/platform.h create mode 100644 CASA-auth-token/client/core/mechanisms/pwd/windows/pwd.vcproj create mode 100644 CASA-auth-token/client/core/mechanisms/pwd/windows/pwmech.def create mode 100644 CASA-auth-token/client/core/test/CASA_Auth.cpp create mode 100644 CASA-auth-token/client/core/test/linux/main.cpp create mode 100755 CASA-auth-token/client/core/test/linux/make.sh create mode 100644 CASA-auth-token/client/core/test/linux/platform.h create mode 100644 CASA-auth-token/client/core/test/windows/main.cpp create mode 100644 CASA-auth-token/client/core/test/windows/platform.h create mode 100644 CASA-auth-token/client/core/test/windows/test.vcproj create mode 100644 CASA-auth-token/client/core/util.c create mode 100644 CASA-auth-token/client/core/windows/Makefile.am create mode 100644 CASA-auth-token/client/core/windows/authtoken.def create mode 100644 CASA-auth-token/client/core/windows/client.vcproj create mode 100644 CASA-auth-token/client/core/windows/dllsup.c create mode 100644 CASA-auth-token/client/core/windows/platform.c create mode 100644 CASA-auth-token/client/core/windows/platform.h create mode 100644 CASA-auth-token/client/core/windows/rpc.c create mode 100644 CASA-auth-token/client/csharp/Novell.Casa.Authtoken/AssemblyInfo.cs create mode 100644 CASA-auth-token/client/csharp/Novell.Casa.Authtoken/AuthToken.snk create mode 100644 CASA-auth-token/client/csharp/Novell.Casa.Authtoken/Authtoken.cs create mode 100644 CASA-auth-token/client/csharp/Novell.Casa.Authtoken/Novell.Casa.Client.csproj create mode 100644 CASA-auth-token/client/csharp/Novell.Casa.Authtoken/WinLuid.cs create mode 100644 CASA-auth-token/client/csharp/README create mode 100644 CASA-auth-token/client/csharp/TODO create mode 100644 CASA-auth-token/client/csharp/test/App.ico create mode 100644 CASA-auth-token/client/csharp/test/AssemblyInfo.cs create mode 100644 CASA-auth-token/client/csharp/test/Class1.cs create mode 100644 CASA-auth-token/client/csharp/test/TestClientAuth.csproj create mode 100644 CASA-auth-token/client/include/Makefile.am create mode 100644 CASA-auth-token/client/include/casa_c_authtoken.h create mode 100644 CASA-auth-token/client/include/list_entry.h create mode 100644 CASA-auth-token/client/include/proto.h create mode 100644 CASA-auth-token/client/include/windows/casa_c_authtoken_ex.h create mode 100644 CASA-auth-token/client/package/Makefile.am create mode 100644 CASA-auth-token/client/package/linux/CASA_auth_token_client.changes create mode 100644 CASA-auth-token/client/package/linux/CASA_auth_token_native.changes create mode 100644 CASA-auth-token/client/package/linux/Makefile.am create mode 100644 CASA-auth-token/client/package/windows/Makefile.am create mode 100644 CASA-auth-token/client/package/windows/authtokenclient_msi/Makefile.am create mode 100644 CASA-auth-token/client/package/windows/authtokenclient_msi/authtokenclient_msi.vdproj create mode 100644 CASA-auth-token/client/package/windows/authtokenclient_msm/Makefile.am create mode 100644 CASA-auth-token/client/package/windows/authtokenclient_msm/authtokenclient_msm.vdproj diff --git a/CASA-auth-token/client/AUTHORS b/CASA-auth-token/client/AUTHORS new file mode 100644 index 00000000..ba13017c --- /dev/null +++ b/CASA-auth-token/client/AUTHORS @@ -0,0 +1,2 @@ +Juan Carlos Luciani - jluciani@novell.com + diff --git a/CASA-auth-token/client/COPYING b/CASA-auth-token/client/COPYING new file mode 100644 index 00000000..b0ab9a23 --- /dev/null +++ b/CASA-auth-token/client/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/client/ChangeLog b/CASA-auth-token/client/ChangeLog new file mode 100644 index 00000000..e69de29b diff --git a/CASA-auth-token/client/Makefile.am b/CASA-auth-token/client/Makefile.am new file mode 100644 index 00000000..c673cb71 --- /dev/null +++ b/CASA-auth-token/client/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 = core package + +DIST_SUBDIRS = include core 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 + if [ -d bin ]; then rm -rf bin; fi + if [ -d lib64 ]; then rm -rf lib64; fi + if [ -d bin64 ]; then rm -rf bin64; fi + +maintainer-clean-local: + rm -f Makefile.in + diff --git a/CASA-auth-token/client/NEWS b/CASA-auth-token/client/NEWS new file mode 100644 index 00000000..e69de29b diff --git a/CASA-auth-token/client/README b/CASA-auth-token/client/README new file mode 100644 index 00000000..48d961e0 --- /dev/null +++ b/CASA-auth-token/client/README @@ -0,0 +1,241 @@ +/*********************************************************************** + * + * 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. + +REQUIREMENTS FOR BUILDING THE SOFTWARE PACKAGE ON WINDOWS + + - Install Visual Studio .NET 2003 + - Install Windows Platform SDK for Windows Server 2003 SP1 + - Register the platform sdk with VS - Start/All Programs/Windows Platform SDK for Windows Server 2003 SP1/Visual Studio Registration/Register PSDK Directories with Visual Studio + - Install Cygwin - See instructions below. + - Extract Expat-2.0.0.zip in casa source directory parent + - Install Casa + +Download and start cygwin install: +Browse to http://sources.redhat.com/cygwin/ + +Click on "Install or update now!" or "Install Cygwin now" + +Cygwin Setup: +Next + +Cygwin Setup - Choose Installation Type: +Install from Internet +Next + +Cygwin Setup - Choose Installation Directory: +Root Directory: C:\cygwin +Install For: "All Users" + +Default Text File Type: DOS + +Cygwin Setup - Select Local Package Directory: + Local Package Directory: C:\cygwin-packages + +Cygwin Setup - Select Connection Type: + Direct Connection + +Choose A Download Site: + ftp://ftp.nas.nasa.gov + +Cywin Setup - Select Packages: + Base: + defaults + + Devel: + autoconf + automake + libtool + make + pkgconfig + cvs + gcc + gcc-g++ + + Editors: + vim (optional) + + Net: + openssh + openssl + + Text: + more + + Utils: + clear (optional) + +Cygwin Setup - Create Icons: +Finish + +Edit cygwin.bat (c:\cygwin\cygwin.bat) to add a call to +%VS71COMNTOOLS%\vsvars32.bat (see example below). This sets up the +Visual Studio tools in Cygwin. + +Sample cygwin.bat: + +@echo off + +call "%VS71COMNTOOLS%\vsvars32.bat" > NUL + +C: +chdir C:\cygwin\bin + +bash --login -i + + +REQUIREMENTS FOR BUILDING THE SOFTWARE PACKAGE ON LINUX + +Install latest mono and mono-devel RPM - Obtain RPMs from +www.go-mono.org. + + +BUILDING THE SOFTWARE PACKAGE + +Windows: Start at Step 1. +Linux: Skip to Step 2. + +1. Run cygwin.bat to start up Cygwin. + +2. Generate autotools files: +./autogen.sh --prefix=/ [--enable-debug] +( is some writable directory where 'make install' will +install files for testing. + +3. To reconfigure later, or to configure software that came from a source +distribution (.tar.gz) file, use configure. +./configure --prefix/ [--enable-debug] +(run ./configure --help for more options) + +4. Select your make target, here are a few interesting ones: + +make [all] - build product files (package files not included) + +make clean - clean up files built by 'make all' + +make package - build product and package files + +make package-clean - clean up package files + +make install - install product files to specified by +--prefix during configure + +make uninstall - undo 'make install' + +make dist - build a source distribution tarball. + +make distclean - removes files to return state back to same as the +source distribution (configure, Makefile.in files, and other distributed +autotools files are not removed) + +make maintainer-clean - removes files to return state back to same as +the CVS checkout (you will need to run ./autogen.sh again before running +make again) + +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/client/TODO b/CASA-auth-token/client/TODO new file mode 100644 index 00000000..ca5a4629 --- /dev/null +++ b/CASA-auth-token/client/TODO @@ -0,0 +1,17 @@ +/*********************************************************************** + * + * 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 + +- Add mechanism to try communicating with ATS over port 443 if communications + over port 2645 fail. diff --git a/CASA-auth-token/client/auth.sln b/CASA-auth-token/client/auth.sln new file mode 100644 index 00000000..a0cbc949 --- /dev/null +++ b/CASA-auth-token/client/auth.sln @@ -0,0 +1,77 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Novell.Casa.Client", "client\csharp\Novell.Casa.Authtoken\Novell.Casa.Client.csproj", "{1BA1FC97-5AF1-4506-A7FD-EBFD46D361A0}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestClientAuth", "client\csharp\test\TestClientAuth.csproj", "{0EA635EA-97F2-4950-B36B-8151ED858DA4}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "client", "client\windows\client.vcproj", "{7BD9A5DB-DE7D-40B7-A397-04182DC2F632}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pwd", "client\mechanisms\pwd\windows\pwd.vcproj", "{5499F624-F371-4559-B4C2-A484BCE892FD}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "krb5", "client\mechanisms\krb5\windows\krb5.vcproj", "{5499F624-F371-4559-B4C2-A484BCE892FD}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "client\test\windows\test.vcproj", "{6034EBF1-0838-45C4-A538-A41A31EC8F46}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "authtokenclient_msm", "package\windows\authtokenclient_msm\authtokenclient_msm.vdproj", "{C8405908-5026-4E77-B02F-9259856A17E8}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "authtokenclient_msi", "package\windows\authtokenclient_msi\authtokenclient_msi.vdproj", "{7B174382-8BE8-4F2A-A122-4FCEE849A776}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {1BA1FC97-5AF1-4506-A7FD-EBFD46D361A0}.Debug.ActiveCfg = Debug|.NET + {1BA1FC97-5AF1-4506-A7FD-EBFD46D361A0}.Debug.Build.0 = Debug|.NET + {1BA1FC97-5AF1-4506-A7FD-EBFD46D361A0}.Release.ActiveCfg = Release|.NET + {1BA1FC97-5AF1-4506-A7FD-EBFD46D361A0}.Release.Build.0 = Release|.NET + {0EA635EA-97F2-4950-B36B-8151ED858DA4}.Debug.ActiveCfg = Debug|.NET + {0EA635EA-97F2-4950-B36B-8151ED858DA4}.Debug.Build.0 = Debug|.NET + {0EA635EA-97F2-4950-B36B-8151ED858DA4}.Release.ActiveCfg = Release|.NET + {0EA635EA-97F2-4950-B36B-8151ED858DA4}.Release.Build.0 = Release|.NET + {7BD9A5DB-DE7D-40B7-A397-04182DC2F632}.Debug.ActiveCfg = Debug|Win32 + {7BD9A5DB-DE7D-40B7-A397-04182DC2F632}.Debug.Build.0 = Debug|Win32 + {7BD9A5DB-DE7D-40B7-A397-04182DC2F632}.Release.ActiveCfg = Release|Win32 + {7BD9A5DB-DE7D-40B7-A397-04182DC2F632}.Release.Build.0 = Release|Win32 + {5499F624-F371-4559-B4C2-A484BCE892FD}.Debug.ActiveCfg = Debug|Win32 + {5499F624-F371-4559-B4C2-A484BCE892FD}.Debug.Build.0 = Debug|Win32 + {5499F624-F371-4559-B4C2-A484BCE892FD}.Release.ActiveCfg = Release|Win32 + {5499F624-F371-4559-B4C2-A484BCE892FD}.Release.Build.0 = Release|Win32 + {5499F624-F371-4559-B4C2-A484BCE892FD}.Debug.ActiveCfg = Debug|Win32 + {5499F624-F371-4559-B4C2-A484BCE892FD}.Debug.Build.0 = Debug|Win32 + {5499F624-F371-4559-B4C2-A484BCE892FD}.Release.ActiveCfg = Release|Win32 + {5499F624-F371-4559-B4C2-A484BCE892FD}.Release.Build.0 = Release|Win32 + {6034EBF1-0838-45C4-A538-A41A31EC8F46}.Debug.ActiveCfg = Debug|Win32 + {6034EBF1-0838-45C4-A538-A41A31EC8F46}.Debug.Build.0 = Debug|Win32 + {6034EBF1-0838-45C4-A538-A41A31EC8F46}.Release.ActiveCfg = Release|Win32 + {6034EBF1-0838-45C4-A538-A41A31EC8F46}.Release.Build.0 = Release|Win32 + {C8405908-5026-4E77-B02F-9259856A17E8}.Debug.ActiveCfg = Debug + {C8405908-5026-4E77-B02F-9259856A17E8}.Debug.Build.0 = Debug + {C8405908-5026-4E77-B02F-9259856A17E8}.Release.ActiveCfg = Release + {C8405908-5026-4E77-B02F-9259856A17E8}.Release.Build.0 = Release + {7B174382-8BE8-4F2A-A122-4FCEE849A776}.Debug.ActiveCfg = Debug + {7B174382-8BE8-4F2A-A122-4FCEE849A776}.Debug.Build.0 = Debug + {7B174382-8BE8-4F2A-A122-4FCEE849A776}.Release.ActiveCfg = Release + {7B174382-8BE8-4F2A-A122-4FCEE849A776}.Release.Build.0 = Release + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/CASA-auth-token/client/autogen.sh b/CASA-auth-token/client/autogen.sh new file mode 100755 index 00000000..19ad55ec --- /dev/null +++ b/CASA-auth-token/client/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_auth_token_native +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/client/configure.in b/CASA-auth-token/client/configure.in new file mode 100644 index 00000000..5b8202fa --- /dev/null +++ b/CASA-auth-token/client/configure.in @@ -0,0 +1,285 @@ +####################################################################### +# +# 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_client, 1.7.795,,CASA_auth_token_client) +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 + BIN=bin64 + ;; + *ia64|*) + LIB=lib + BIN=bin + ;; +esac + +AC_SUBST(LIB) +AC_SUBST(BIN) +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/windows/Makefile +package/windows/authtokenclient_msm/Makefile +package/windows/authtokenclient_msi/Makefile +package/linux/CASA_auth_token_client.spec +include/Makefile +core/Makefile +core/linux/Makefile +core/windows/Makefile +core/mechanisms/Makefile +core/mechanisms/pwd/Makefile +core/mechanisms/pwd/linux/Makefile +core/mechanisms/pwd/windows/Makefile +core/mechanisms/krb5/Makefile +core/mechanisms/krb5/linux/Makefile +core/mechanisms/krb5/windows/Makefile +]) + diff --git a/CASA-auth-token/client/core/Makefile.am b/CASA-auth-token/client/core/Makefile.am new file mode 100644 index 00000000..0dc5025c --- /dev/null +++ b/CASA-auth-token/client/core/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 = $(TARGET_OS) mechanisms + +DIST_SUBDIRS = linux windows mechanisms + +CFILES = + +EXTRA_DIST = $(CFILES) *.h client.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/client/core/README b/CASA-auth-token/client/core/README new file mode 100644 index 00000000..60986c80 --- /dev/null +++ b/CASA-auth-token/client/core/README @@ -0,0 +1,90 @@ +/*********************************************************************** + * + * 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 libcasa_c_authtoken + * + ***********************************************************************/ + +INTRODUCTION + +libcasa_c_authtoken is the client auth_token engine. It is responsible for +interacting with ATSs, invoking the authentication mechanism plug-ins, and +managing the authentication token cache. libcasa_c_authtoken also provides +the Get Authentication Token API. + +CONFIGURING ADDITIONAL AUTHENTICATION MECHANISM MODULES + +libcasa_c_authtoken utilizes mechanism plug-ins for authenticating to ATSs. +The client auth_token package installs mechanisms for the support of Kerberos5 +and Username/Password authentication. To configure additional authentication mechanism +plug-ins, place their configuration file in the folder for CASA Authentication Token module +configuration. The path to this folder under linux is /etc/CASA/authtoken/client/mechanisms/. +The path to this folder under Windows is \Program Files\novell\CASA\Etc\Auth\Mechanisms\. The name of +the plug-in configuration file is related to the authentication mechanism type in the following +manner: AuthenticationMechanismTypeName.conf. + +Authentication Mechanism plug-in configuration files must must contain a directive indicating the +path to the library implementing the Authentication Mechanism (See the configuration file +for the Kr5Authenticate plug-in for an example). + +CLIENT APPLICATION PROGRAMMING NOTES + +The Get CASA Authentication Token API is defined in casa_c_authtoken.h. + +The API consists of a call to obtain authentication tokens. The caller must supply the name of the +service to which it wants to authenticate along with the name of the host where it resides. The +returned authentication token is a Base64 encoded string. + +Applications utilizing CASA Authentication Tokens as passwords in protocols that require the +transfer of user name and password credentials should verify or remove any password length limits +as the length of CASA Authentication Tokens may be over 1K bytes. The size of the CASA Authentication +Tokens is directly dependent on the amount of identity information configured as required by the +consuming service. These applications should also set the user name to "CasaPrincipal". + +For examples of code which uses the Get CASA Authentication Token API look at the test application +under the test folder. + +AUTHENTICATION MECHANISM PROGRAMMING NOTES + +The Authentication Mechanism API is defined in mech_if.h. + +For example implementations see the code for the krb5 and the pwd mechanisms. + +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/client/core/TODO b/CASA-auth-token/client/core/TODO new file mode 100644 index 00000000..07ce4dc8 --- /dev/null +++ b/CASA-auth-token/client/core/TODO @@ -0,0 +1,13 @@ +/*********************************************************************** + * + * TODO for libcasa_c_authtoken + * + ***********************************************************************/ + +INTRODUCTION + +This file contains a list of the items still outstanding for libcasa_c_authtoken. + +OUTSTANDING ITEMS + +None. diff --git a/CASA-auth-token/client/core/authmech.c b/CASA-auth-token/client/core/authmech.c new file mode 100644 index 00000000..39652cb6 --- /dev/null +++ b/CASA-auth-token/client/core/authmech.c @@ -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 + * + ***********************************************************************/ + + +//===[ Include files ]===================================================== + +#include "internal.h" + +//===[ Type definitions ]================================================== + +// +// AuthMechMod definition +// +typedef struct _AuthMechMod +{ + LIST_ENTRY listEntry; + char *pAuthTypeName; + int authTypeNameLen; + LIB_HANDLE libHandle; + AuthTokenIf *pAuthTokenIf; + +} AuthMechMod, *PAuthMechMod; + + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + +// AuthMechModule List and syncronizing mutex +static +LIST_ENTRY g_authMechModuleListHead = {&g_authMechModuleListHead, + &g_authMechModuleListHead}; + + +//++======================================================================= +static +CasaStatus +GetAuthTokenIf( + IN const char *pAuthTypeName, + INOUT AuthTokenIf **ppAuthTokenIf) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// Environment: +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus; + ConfigIf *pModuleConfigIf; + + DbgTrace(2, "-GetAuthTokenIf- Start\n", 0); + + // Get the configuration for the module + retStatus = GetConfigInterface(mechConfigFolder, + pAuthTypeName, + &pModuleConfigIf); + if (CASA_SUCCESS(retStatus) + && CasaStatusCode(retStatus) != CASA_STATUS_OBJECT_NOT_FOUND) + { + LIST_ENTRY *pListEntry; + AuthMechMod *pAuthMechMod = NULL; + int authTypeNameLen = strlen(pAuthTypeName); + + // Look if we already have the module in our list + pListEntry = g_authMechModuleListHead.Flink; + while (pListEntry != &g_authMechModuleListHead) + { + // Get pointer to the current entry + pAuthMechMod = CONTAINING_RECORD(pListEntry, AuthMechMod, listEntry); + + // Check if this is the module that we need + if (pAuthMechMod->authTypeNameLen == authTypeNameLen + && memcmp(pAuthTypeName, pAuthMechMod->pAuthTypeName, authTypeNameLen) == 0) + { + // This is the module that we need, stop looking. + break; + } + else + { + // This is not the module that we are looking for + pAuthMechMod = NULL; + } + + // Advance to the next entry + pListEntry = pListEntry->Flink; + } + + // Proceed based on whether or not a module was found + if (pAuthMechMod) + { + // Module found in our list, provide the caller with its AuthTokenIf + // instance after we have incremented its reference count. + pAuthMechMod->pAuthTokenIf->addReference(pAuthMechMod->pAuthTokenIf); + *ppAuthTokenIf = pAuthMechMod->pAuthTokenIf; + + // Success + retStatus = CASA_STATUS_SUCCESS; + } + else + { + // Needed module not found in our list, create an entry. + pAuthMechMod = (AuthMechMod*) malloc(sizeof(*pAuthMechMod)); + if (pAuthMechMod) + { + // Allocate buffer to contain the authentication type name within the module entry + pAuthMechMod->pAuthTypeName = (char*) malloc(authTypeNameLen + 1); + if (pAuthMechMod->pAuthTypeName) + { + char *pLibraryName; + + // Initialize the library handle field + pAuthMechMod->libHandle = NULL; + + // Save the auth type name within the entry + strcpy(pAuthMechMod->pAuthTypeName, pAuthTypeName); + pAuthMechMod->authTypeNameLen = authTypeNameLen; + + // Obtain the name of the library that we must load + pLibraryName = pModuleConfigIf->getEntryValue(pModuleConfigIf, "LibraryName"); + if (pLibraryName) + { + // Load the library + pAuthMechMod->libHandle = OpenLibrary(pLibraryName); + if (pAuthMechMod->libHandle) + { + PFN_GetAuthTokenIfRtn pGetAuthTokenIfRtn; + + // Library has been loaded, now get a pointer to its GetAuthTokenInterface routine + pGetAuthTokenIfRtn = (PFN_GetAuthTokenIfRtn) GetFunctionPtr(pAuthMechMod->libHandle, + GET_AUTH_TOKEN_INTERFACE_RTN_SYMBOL); + if (pGetAuthTokenIfRtn) + { + // Now, obtain the modules AuthTokenIf. + retStatus = (pGetAuthTokenIfRtn)(pModuleConfigIf, &pAuthMechMod->pAuthTokenIf); + } + else + { + DbgTrace(0, "-GetAuthTokenIf- GetFunctionPtr\n", 0); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_LIBRARY_LOAD_FAILURE); + } + } + else + { + DbgTrace(0, "-GetAuthTokenIf- OpenLibrary error\n", 0); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_UNSUCCESSFUL); + } + + // Free the buffer holding the library name + free(pLibraryName); + } + else + { + DbgTrace(0, "-GetAuthTokenIf- Library name not configured\n", 0); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_CONFIGURATION_ERROR); + } + + // Check if we were successful at obtaining the AuthTokenIf instance for the + // module. + if (CASA_SUCCESS(retStatus)) + { + // Insert the entry in the list, provide the caller with its AuthTokenIf + // instance after we have incremented its reference count. + InsertTailList(&g_authMechModuleListHead, &pAuthMechMod->listEntry); + pAuthMechMod->pAuthTokenIf->addReference(pAuthMechMod->pAuthTokenIf); + *ppAuthTokenIf = pAuthMechMod->pAuthTokenIf; + } + else + { + // Failed, free resources. + free(pAuthMechMod->pAuthTypeName); + if (pAuthMechMod->libHandle) + CloseLibrary(pAuthMechMod->libHandle); + free(pAuthMechMod); + } + } + else + { + DbgTrace(0, "GetAuthTokenIf-GetAuthTokenIf- Unable to allocate buffer\n", 0); + + // Free buffer allocated for entry + free(pAuthMechMod); + + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + } + else + { + DbgTrace(0, "-GetAuthTokenIf- Unable to allocate buffer\n", 0); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + } + + // Release config interface instance + pModuleConfigIf->releaseReference(pModuleConfigIf); + } + else + { + DbgTrace(0, "-GetAuthTokenIf- Unable to obtain config interface\n", 0); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_CONFIGURATION_ERROR); + } + + DbgTrace(2, "-GetAuthTokenIf- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +CasaStatus +GetAuthMechToken( + IN AuthContext *pAuthContext, + IN const char *pHostName, + IN void *pCredStoreScope, + INOUT char **ppAuthToken) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_UNSUCCESSFUL); + AuthTokenIf *pAuthTokenIf = NULL; + + DbgTrace(1, "-GetAuthMechToken- Start\n", 0); + + // Initialize output parameter + *ppAuthToken = NULL; + + // Obtain the appropriate token interface for the authentication type + retStatus = GetAuthTokenIf(pAuthContext->pMechanism, + &pAuthTokenIf); + if (CASA_SUCCESS(retStatus)) + { + char *pAuthToken = NULL; + int authTokenBufLen = 0; + + // We found a provider for the service, query it for the buffer size + // needed to obtain the authentication token. + retStatus = pAuthTokenIf->getAuthToken(pAuthTokenIf, + pAuthContext->pContext, + pAuthContext->pMechInfo, + pHostName, + pCredStoreScope, + pAuthToken, + &authTokenBufLen); + if (CasaStatusCode(retStatus) == CASA_STATUS_BUFFER_OVERFLOW) + { + // Allocate buffer to hold the authentication token + pAuthToken = (char*) malloc(authTokenBufLen); + if (pAuthToken) + { + // Request the token from the provider + retStatus = pAuthTokenIf->getAuthToken(pAuthTokenIf, + pAuthContext->pContext, + pAuthContext->pMechInfo, + pHostName, + pCredStoreScope, + pAuthToken, + &authTokenBufLen); + if (CASA_SUCCESS(retStatus)) + { + // Return the buffer containing the token to the caller + *ppAuthToken = pAuthToken; + } + else + { + // Free the allocated buffer + free(pAuthToken); + } + } + else + { + DbgTrace(0, "-GetAuthMechToken- Buffer allocation failure\n", 0); + } + } + + // Release token interface + pAuthTokenIf->releaseReference(pAuthTokenIf); + } + else + { + // No authentication token interface available for authentication type + DbgTrace(0, "-GetAuthMechToken- Failed to obtain auth mech token interface\n", 0); + } + + DbgTrace(1, "-GetAuthMechToken- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +//++======================================================================= +//++======================================================================= + diff --git a/CASA-auth-token/client/core/authmsg.c b/CASA-auth-token/client/core/authmsg.c new file mode 100644 index 00000000..a55631f2 --- /dev/null +++ b/CASA-auth-token/client/core/authmsg.c @@ -0,0 +1,803 @@ +/*********************************************************************** + * + * 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 + * + ***********************************************************************/ + + +//===[ Include files ]===================================================== + +#include "internal.h" + +//===[ Type definitions ]================================================== + +// +// Parse states +// +#define AWAITING_ROOT_ELEMENT_START 0x0 +#define AWAITING_ROOT_ELEMENT_END 0x1 +#define AWAITING_STATUS_ELEMENT_START 0x2 +#define AWAITING_STATUS_ELEMENT_END 0x3 +#define AWAITING_STATUS_DATA 0x4 +#define AWAITING_DESCRIPTION_ELEMENT_START 0x5 +#define AWAITING_DESCRIPTION_ELEMENT_END 0x6 +#define AWAITING_DESCRIPTION_DATA 0x7 +#define AWAITING_SESSION_TOKEN_ELEMENT_START 0x8 +#define AWAITING_SESSION_TOKEN_ELEMENT_END 0x9 +#define AWAITING_SESSION_TOKEN_DATA 0xA +#define AWAITING_LIFETIME_DATA 0xB +#define AWAITING_LIFETIME_ELEMENT_START 0xC +#define AWAITING_LIFETIME_ELEMENT_END 0xD +#define AWAITING_AUTH_TOKEN_ELEMENT_START 0xE +#define AWAITING_AUTH_TOKEN_ELEMENT_END 0xF +#define AWAITING_AUTH_TOKEN_DATA 0x10 +#define AWAITING_REALM_DATA 0x12 +#define AWAITING_REALM_ELEMENT_END 0x13 +#define DONE_PARSING 0x14 + +// +// Authentication Response Parse Structure +// +typedef struct _AuthRespParse +{ + XML_Parser p; + int state; + int elementDataProcessed; + AuthenticateResp *pAuthenticateResp; + CasaStatus status; + +} AuthRespParse, *PAuthRespParse; + + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + +//++======================================================================= +char* +BuildAuthenticateMsg( + IN AuthContext *pAuthContext, + IN char *pAuthMechToken) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + char *pMsg = NULL; + int bufferSize; + + DbgTrace(1, "-BuildAuthenticateMsg- Start\n", 0); + + /* + * The format of the authentication request message is as follows: + * + * + * + * realm value + * mechanism id value + * authentication mechanism token data + * + * + */ + + // Determine the buffer size necessary to hold the msg + bufferSize = strlen(XML_DECLARATION) + + 2 // crlf + + 1 // < + + strlen(AUTH_REQUEST_ELEMENT_NAME) + + 3 // >crlf + + 1 // < + + strlen(REALM_ELEMENT_NAME) + + 1 // > + + strlen(pAuthContext->pContext) + + 2 // crlf + + 1 // < + + strlen(MECHANISM_ELEMENT_NAME) + + 1 // > + + strlen(pAuthContext->pMechanism) + + 2 // crlf + + 1 // < + + strlen(AUTH_MECH_TOKEN_ELEMENT_NAME) + + 1 // > + + strlen(pAuthMechToken) + + 2 // crlf + + 2 // null + + // Allocate the msg buffer + pMsg = (char*) malloc(bufferSize); + if (pMsg) + { + // Now build the message + memset(pMsg, 0, bufferSize); + strcat(pMsg, XML_DECLARATION); + strcat(pMsg, "\r\n"); + strcat(pMsg, "<"); + strcat(pMsg, AUTH_REQUEST_ELEMENT_NAME); + strcat(pMsg, ">\r\n"); + strcat(pMsg, "<"); + strcat(pMsg, REALM_ELEMENT_NAME); + strcat(pMsg, ">"); + strcat(pMsg, pAuthContext->pContext); + strcat(pMsg, "\r\n"); + strcat(pMsg, "<"); + strcat(pMsg, MECHANISM_ELEMENT_NAME); + strcat(pMsg, ">"); + strcat(pMsg, pAuthContext->pMechanism); + strcat(pMsg, "\r\n"); + strcat(pMsg, "<"); + strcat(pMsg, AUTH_MECH_TOKEN_ELEMENT_NAME); + strcat(pMsg, ">"); + strcat(pMsg, pAuthMechToken); + strcat(pMsg, "\r\n"); + strcat(pMsg, ""); + } + else + { + DbgTrace(0, "-BuildAuthenticateMsg- Buffer allocation error\n", 0); + } + + DbgTrace(1, "-BuildAuthenticateMsg- End, pMsg = %0lX\n", (long) pMsg); + + return pMsg; +} + + +//++======================================================================= +static +void XMLCALL +AuthRespStartElementHandler( + IN AuthRespParse *pAuthRespParse, + IN const XML_Char *name, + IN const XML_Char **atts) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + DbgTrace(2, "-AuthRespStartElementHandler- Start\n", 0); + + // Proceed based on the state + switch (pAuthRespParse->state) + { + case AWAITING_ROOT_ELEMENT_START: + + // In this state, we are only expecting the Authentication + // Response Element. + if (strcmp(name, AUTH_RESPONSE_ELEMENT_NAME) == 0) + { + // Good, advance to the next state. + pAuthRespParse->state = AWAITING_STATUS_ELEMENT_START; + } + else + { + DbgTrace(0, "-AuthRespStartElementHandler- Un-expected start element\n", 0); + XML_StopParser(pAuthRespParse->p, XML_FALSE); + } + break; + + case AWAITING_STATUS_ELEMENT_START: + + // In this state, we are only expecting the Status Element. + if (strcmp(name, STATUS_ELEMENT_NAME) == 0) + { + // Good, advance to the next state. + pAuthRespParse->state = AWAITING_DESCRIPTION_ELEMENT_START; + } + else + { + DbgTrace(0, "-AuthRespStartElementHandler- Un-expected start element\n", 0); + XML_StopParser(pAuthRespParse->p, XML_FALSE); + } + break; + + case AWAITING_DESCRIPTION_ELEMENT_START: + + // In this state, we are only expecting the Description Element. + if (strcmp(name, DESCRIPTION_ELEMENT_NAME) == 0) + { + // Good, advance to the next state. + pAuthRespParse->state = AWAITING_DESCRIPTION_DATA; + } + else + { + DbgTrace(0, "-AuthRespStartElementHandler- Un-expected start element\n", 0); + XML_StopParser(pAuthRespParse->p, XML_FALSE); + } + break; + + case AWAITING_SESSION_TOKEN_ELEMENT_START: + + // In this state, we are only expecting the Session Token Element. + if (strcmp(name, SESSION_TOKEN_ELEMENT_NAME) == 0) + { + // Good, advance to the next state. + pAuthRespParse->state = AWAITING_LIFETIME_ELEMENT_START; + } + else + { + DbgTrace(0, "-AuthRespStartElementHandler- Un-expected start element\n", 0); + XML_StopParser(pAuthRespParse->p, XML_FALSE); + } + break; + + case AWAITING_LIFETIME_ELEMENT_START: + + // In this state, we are only expecting the Lifetime Element. + if (strcmp(name, LIFETIME_ELEMENT_NAME) == 0) + { + // Good, advance to the next state. + pAuthRespParse->state = AWAITING_LIFETIME_DATA; + } + else + { + DbgTrace(0, "-AuthRespStartElementHandler- Un-expected start element\n", 0); + XML_StopParser(pAuthRespParse->p, XML_FALSE); + } + break; + + default: + DbgTrace(0, "-AuthRespStartElementHandler- Un-expected state = %d\n", pAuthRespParse->state); + XML_StopParser(pAuthRespParse->p, XML_FALSE); + break; + } + + DbgTrace(2, "-AuthRespStartElementHandler- End\n", 0); +} + + +//++======================================================================= +static +CasaStatus +ConsumeElementData( + IN AuthRespParse *pAuthRespParse, + IN const XML_Char *s, + IN int len, + INOUT char **ppElementData, + INOUT int *pElementDataLen) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus = CASA_STATUS_SUCCESS; + + DbgTrace(3, "-ConsumeElementData- Start\n", 0); + + // Proceed based on whether or not we have already consumed data + // for this element. + if (*ppElementData == NULL) + { + // We have not yet consumed data for this element + pAuthRespParse->elementDataProcessed = len; + + // Allocate a buffer to hold this element data (null terminated). + *ppElementData = (char*) malloc(len + 1); + if (*ppElementData) + { + memset(*ppElementData, 0, len + 1); + memcpy(*ppElementData, s, len); + + // Return the length of the element data buffer + *pElementDataLen = pAuthRespParse->elementDataProcessed + 1; + } + else + { + DbgTrace(0, "-ConsumeElementData- Buffer allocation failure\n", 0); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + } + else + { + char *pNewBuf; + + // We have already received token data, append this data to it. + pNewBuf = (char*) malloc(pAuthRespParse->elementDataProcessed + len + 1); + if (pNewBuf) + { + memset(pNewBuf, + 0, + pAuthRespParse->elementDataProcessed + len + 1); + memcpy(pNewBuf, + *ppElementData, + pAuthRespParse->elementDataProcessed); + memcpy(pNewBuf + pAuthRespParse->elementDataProcessed, s, len); + pAuthRespParse->elementDataProcessed += len; + + // Swap the buffers + free(*ppElementData); + *ppElementData = pNewBuf; + + // Return the length of the element data buffer + *pElementDataLen = pAuthRespParse->elementDataProcessed + 1; + } + else + { + DbgTrace(0, "-ConsumeElementData- Buffer allocation failure\n", 0); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + } + + DbgTrace(3, "-ConsumeElementData- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +static +void XMLCALL +AuthRespCharDataHandler( + IN AuthRespParse *pAuthRespParse, + IN const XML_Char *s, + IN int len) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + DbgTrace(2, "-AuthRespCharDataHandler- Start\n", 0); + + // Just exit if being called to process white space + if (*s == '\n' || *s == '\r' || *s == '\t' || *s == ' ') + { + goto exit; + } + + // Proceed based on the state + switch (pAuthRespParse->state) + { + case AWAITING_DESCRIPTION_DATA: + case AWAITING_DESCRIPTION_ELEMENT_END: + + // Ignore the status description data for now. + // tbd + + // Advanced to the next state + pAuthRespParse->state = AWAITING_DESCRIPTION_ELEMENT_END; + break; + + case AWAITING_STATUS_DATA: + + // Set the appropriate status in the AuthenticationResp based on the + // returned status. + if (strncmp(HTTP_OK_STATUS_CODE, s, len) == 0) + { + pAuthRespParse->status = CASA_STATUS_SUCCESS; + } + else if (strncmp(HTTP_UNAUTHORIZED_STATUS_CODE, s, len) == 0) + { + pAuthRespParse->status = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_AUTHENTICATION_FAILURE); + } + else if (strncmp(HTTP_NOT_FOUND_STATUS_CODE, s, len) == 0) + { + pAuthRespParse->status = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_CONFIGURATION_ERROR); + } + else if (strncmp(HTTP_SERVER_ERROR_STATUS_CODE, s, len) == 0) + { + pAuthRespParse->status = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_SERVER_ERROR); + } + else + { + DbgTrace(0, "-AuthRespCharDataHandler- Un-expected status\n", 0); + pAuthRespParse->status = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_UNSUCCESSFUL); + } + + // Advanced to the next state + pAuthRespParse->state = AWAITING_STATUS_ELEMENT_END; + break; + + case AWAITING_LIFETIME_DATA: + + // Convert the lifetime string to a numeric value + pAuthRespParse->pAuthenticateResp->tokenLifetime = dtoul(s, len); + + // Advanced to the next state + pAuthRespParse->state = AWAITING_LIFETIME_ELEMENT_END; + break; + + case AWAITING_SESSION_TOKEN_DATA: + case AWAITING_SESSION_TOKEN_ELEMENT_END: + + // Consume the data + pAuthRespParse->status = ConsumeElementData(pAuthRespParse, + s, + len, + &pAuthRespParse->pAuthenticateResp->pToken, + &pAuthRespParse->pAuthenticateResp->tokenLen); + if (CASA_SUCCESS(pAuthRespParse->status)) + { + // Advanced to the next state + pAuthRespParse->state = AWAITING_SESSION_TOKEN_ELEMENT_END; + } + else + { + XML_StopParser(pAuthRespParse->p, XML_FALSE); + } + break; + + default: + DbgTrace(0, "-AuthRespCharDataHandler- Un-expected state = %d\n", pAuthRespParse->state); + XML_StopParser(pAuthRespParse->p, XML_FALSE); + break; + } + +exit: + + DbgTrace(2, "-AuthRespCharDataHandler- End\n", 0); +} + + +//++======================================================================= +static +void XMLCALL +AuthRespEndElementHandler( + IN AuthRespParse *pAuthRespParse, + IN const XML_Char *name) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + DbgTrace(2, "-AuthRespEndElementHandler- Start\n", 0); + + // Proceed based on the state + switch (pAuthRespParse->state) + { + case AWAITING_ROOT_ELEMENT_END: + + // In this state, we are only expecting the Authentication + // Response Element. + if (strcmp(name, AUTH_RESPONSE_ELEMENT_NAME) == 0) + { + // Done. + pAuthRespParse->state = DONE_PARSING; + } + else + { + DbgTrace(0, "-AuthRespEndHandler- Un-expected end element\n", 0); + XML_StopParser(pAuthRespParse->p, XML_FALSE); + } + break; + + case AWAITING_DESCRIPTION_ELEMENT_END: + + // In this state, we are only expecting the Description Element. + if (strcmp(name, DESCRIPTION_ELEMENT_NAME) == 0) + { + // Good, advance to the next state. + pAuthRespParse->state = AWAITING_STATUS_DATA; + } + else + { + DbgTrace(0, "-AuthRespEndElementHandler- Un-expected end element\n", 0); + XML_StopParser(pAuthRespParse->p, XML_FALSE); + } + break; + + case AWAITING_STATUS_ELEMENT_END: + + // In this state, we are only expecting the Status Element. + if (strcmp(name, STATUS_ELEMENT_NAME) == 0) + { + // Good, advance to the next state based on the status code. + if (CASA_SUCCESS(pAuthRespParse->status)) + { + // The request completed successfully + pAuthRespParse->state = AWAITING_SESSION_TOKEN_ELEMENT_START; + } + else + { + pAuthRespParse->state = AWAITING_ROOT_ELEMENT_END; + } + } + else + { + DbgTrace(0, "-AuthRespEndElementHandler- Un-expected start element\n", 0); + XML_StopParser(pAuthRespParse->p, XML_FALSE); + } + break; + + case AWAITING_LIFETIME_ELEMENT_END: + + // In this state, we are only expecting the Lifetime Element. + if (strcmp(name, LIFETIME_ELEMENT_NAME) == 0) + { + // Good, advance to the next state. + pAuthRespParse->state = AWAITING_SESSION_TOKEN_DATA; + } + else + { + DbgTrace(0, "-AuthRespEndElementHandler- Un-expected start element\n", 0); + XML_StopParser(pAuthRespParse->p, XML_FALSE); + } + break; + + case AWAITING_SESSION_TOKEN_ELEMENT_END: + + // In this state, we are only expecting the Session Token Element. + if (strcmp(name, SESSION_TOKEN_ELEMENT_NAME) == 0) + { + // Good, advance to the next state. + pAuthRespParse->state = AWAITING_ROOT_ELEMENT_END; + } + else + { + DbgTrace(0, "-AuthRespEndElementHandler- Un-expected start element\n", 0); + XML_StopParser(pAuthRespParse->p, XML_FALSE); + } + break; + + default: + DbgTrace(0, "-AuthRespEndElementHandler- Un-expected state = %d\n", pAuthRespParse->state); + XML_StopParser(pAuthRespParse->p, XML_FALSE); + break; + } + + DbgTrace(2, "-AuthRespEndElementHandler- End\n", 0); +} + + +//++======================================================================= +CasaStatus +CreateAuthenticateResp( + IN char *pRespMsg, + IN int respLen, + INOUT AuthenticateResp **ppAuthenticateResp) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus = CASA_STATUS_SUCCESS; + AuthRespParse authRespParse = {0}; + AuthenticateResp *pAuthenticateResp; + + DbgTrace(1, "-CreateAuthenticateResp- Start\n", 0); + + /* + * When an authentication request is processed successfully, the server replies to + * the client with a message with the following format: + * + * + * + * ok200 + * lifetime valuesession token data + * + * + * When an authentication request fails to be successfully processed, the server + * responds with an error and an error description string. The message format of + * an unsuccessful reply is as follows: + * + * + * + * status descriptionstatus code + * + * + * Plase note that the protocol utilizes the status codes defined + * in the HTTP 1.1 Specification. + * + */ + + // Allocate AuthenticateResp object + pAuthenticateResp = malloc(sizeof(*pAuthenticateResp)); + if (pAuthenticateResp) + { + XML_Parser p; + + // Initialize the AuthenticateResp object and set it in the + // authentication response parse oject. + memset(pAuthenticateResp, 0, sizeof(*pAuthenticateResp)); + authRespParse.pAuthenticateResp = pAuthenticateResp; + + // Create parser + p = XML_ParserCreate(NULL); + if (p) + { + // Keep track of the parser in our parse object + authRespParse.p = p; + + // Initialize the status within the parse object + authRespParse.status = CASA_STATUS_SUCCESS; + + // Set the start and end element handlers + XML_SetElementHandler(p, + (XML_StartElementHandler) AuthRespStartElementHandler, + (XML_EndElementHandler) AuthRespEndElementHandler); + + // Set the character data handler + XML_SetCharacterDataHandler(p, (XML_CharacterDataHandler) AuthRespCharDataHandler); + + + // Set our user data + XML_SetUserData(p, &authRespParse); + + // Parse the document + if (XML_Parse(p, pRespMsg, respLen, 1) == XML_STATUS_OK) + { + // Verify that the parse operation completed successfully + if (authRespParse.state == DONE_PARSING) + { + // The parse operation succeded, obtain the status returned + // by the server. + retStatus = authRespParse.status; + } + else + { + DbgTrace(0, "-CreateAuthenticateResp- Parse operation did not complete\n", 0); + + // Check if a status has been recorded + if (authRespParse.status != CASA_STATUS_SUCCESS) + { + retStatus = authRespParse.status; + } + else + { + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_PROTOCOL_ERROR); + } + } + } + else + { + DbgTrace(0, "-CreateAuthenticateResp- Parse error %d\n", XML_GetErrorCode(p)); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_PROTOCOL_ERROR); + } + + // Free the parser + XML_ParserFree(p); + } + else + { + DbgTrace(0, "-CreateAuthenticateResp- Parser creation error\n", 0); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + + // Return the AuthenticationResp object to the caller if necessary + if (CASA_SUCCESS(retStatus)) + { + *ppAuthenticateResp = pAuthenticateResp; + } + else + { + free(pAuthenticateResp); + } + } + else + { + DbgTrace(0, "-CreateAuthenticateResp- Memory allocation error\n", 0); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + + DbgTrace(1, "-CreateAuthenticateResp- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +void +RelAuthenticateResp( + IN AuthenticateResp *pAuthenticateResp) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + DbgTrace(1, "-RelAuthenticateResp- Start\n", 0); + + // Free the resources associated with the object + if (pAuthenticateResp->pToken) + free(pAuthenticateResp->pToken); + + free(pAuthenticateResp); + + DbgTrace(1, "-RelAuthenticateResp- End\n", 0); +} + + +//++======================================================================= +//++======================================================================= +//++======================================================================= + diff --git a/CASA-auth-token/client/core/authpolicy.c b/CASA-auth-token/client/core/authpolicy.c new file mode 100644 index 00000000..9abeab7e --- /dev/null +++ b/CASA-auth-token/client/core/authpolicy.c @@ -0,0 +1,804 @@ +/*********************************************************************** + * + * 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 + * + ***********************************************************************/ + + +//===[ Include files ]===================================================== + +#include "internal.h" + +//===[ Type definitions ]================================================== + +// +// Parse states +// +#define AWAITING_ROOT_ELEMENT_START 0x0 +#define AWAITING_ROOT_ELEMENT_END 0x1 +#define AWAITING_AUTH_POLICY_ELEMENT_START 0x2 +#define AWAITING_AUTH_POLICY_ELEMENT_END 0x3 +#define AWAITING_AUTH_POLICY_DATA 0x4 +#define AWAITING_AUTH_SOURCE_ELEMENT_START 0x5 +#define AWAITING_AUTH_SOURCE_ELEMENT_END 0x6 +#define AWAITING_AUTH_SOURCE_CHILD_START 0x7 +#define AWAITING_REALM_DATA 0x8 +#define AWAITING_REALM_ELEMENT_END 0x9 +#define AWAITING_MECHANISM_DATA 0xA +#define AWAITING_MECHANISM_ELEMENT_END 0xB +#define AWAITING_MECHANISM_INFO_DATA 0xC +#define AWAITING_MECHANISM_INFO_ELEMENT_END 0xD +#define AWAITING_UNKNOWN_DATA 0xE +#define AWAITING_UNKNOWN_ELEMENT_END 0xF +#define DONE_PARSING 0x10 + +// +// Authentication Policy Parse Structure +// +typedef struct _AuthPolicyParse +{ + XML_Parser p; + int state; + int elementDataProcessed; + AuthPolicy *pAuthPolicy; + CasaStatus status; + +} AuthPolicyParse, *PAuthPolicyParse; + + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + +//++======================================================================= +static +void XMLCALL +AuthPolicyStartElementHandler( + IN AuthPolicyParse *pAuthPolicyParse, + IN const XML_Char *name, + IN const XML_Char **atts) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + DbgTrace(2, "-AuthPolicyStartElementHandler- Start\n", 0); + + // Proceed based on the state + switch (pAuthPolicyParse->state) + { + case AWAITING_ROOT_ELEMENT_START: + + // In this state, we are only expecting the Authentication + // Policy Element. + if (strcmp(name, AUTH_POLICY_ELEMENT_NAME) == 0) + { + // Good, advance to the next state. + pAuthPolicyParse->state = AWAITING_AUTH_SOURCE_ELEMENT_START; + } + else + { + DbgTrace(0, "-AuthPolicyStartElementHandler- Un-expected start element\n", 0); + XML_StopParser(pAuthPolicyParse->p, XML_FALSE); + } + break; + + case AWAITING_AUTH_SOURCE_ELEMENT_START: + case AWAITING_ROOT_ELEMENT_END: + + // In this state, we are only expecting the start of an Authentication + // Source Element. + if (strcmp(name, AUTH_SOURCE_ELEMENT_NAME) == 0) + { + AuthContext *pAuthContext; + + // Create an authentication context structure + pAuthContext = (AuthContext*) malloc(sizeof(AuthContext)); + if (pAuthContext) + { + // Initialize the allocated AuthContext structure and associate it + // with the AuthPolicy structure. + memset(pAuthContext, 0, sizeof(*pAuthContext)); + InsertTailList(&pAuthPolicyParse->pAuthPolicy->authContextListHead, &pAuthContext->listEntry); + + // Good, advance to the next state. + pAuthPolicyParse->state = AWAITING_AUTH_SOURCE_CHILD_START; + } + else + { + DbgTrace(0, "-AuthPolicyStartElementHandler- Buffer allocation error\n", 0); + XML_StopParser(pAuthPolicyParse->p, XML_FALSE); + } + } + else + { + DbgTrace(0, "-AuthPolicyStartElementHandler- Un-expected start element\n", 0); + XML_StopParser(pAuthPolicyParse->p, XML_FALSE); + } + break; + + case AWAITING_AUTH_SOURCE_CHILD_START: + + // Proceed based on the name of the element + if (strcmp(name, REALM_ELEMENT_NAME) == 0) + { + // Advance to the next state. + pAuthPolicyParse->state = AWAITING_REALM_DATA; + } + else if (strcmp(name, MECHANISM_ELEMENT_NAME) == 0) + { + // Advance to the next state. + pAuthPolicyParse->state = AWAITING_MECHANISM_DATA; + } + else if (strcmp(name, MECHANISM_INFO_ELEMENT_NAME) == 0) + { + // Advance to the next state. + pAuthPolicyParse->state = AWAITING_MECHANISM_INFO_DATA; + } + else if (strcmp(name, AUTH_SOURCE_ELEMENT_NAME) == 0) + { + // We are starting a new auth source entry, create an authentication + // context structure to hold its information. + AuthContext *pAuthContext; + + // Create an authentication context structure + pAuthContext = (AuthContext*) malloc(sizeof(AuthContext)); + if (pAuthContext) + { + // Initialize the allocated AuthContext structure and associate it + // with the AuthPolicy structure. + memset(pAuthContext, 0, sizeof(*pAuthContext)); + InsertTailList(&pAuthPolicyParse->pAuthPolicy->authContextListHead, &pAuthContext->listEntry); + } + else + { + DbgTrace(0, "-AuthPolicyStartElementHandler- Buffer allocation error\n", 0); + XML_StopParser(pAuthPolicyParse->p, XML_FALSE); + } + } + else + { + // Advance to the next state. + pAuthPolicyParse->state = AWAITING_UNKNOWN_DATA; + } + break; + + default: + DbgTrace(0, "-AuthPolicyStartElementHandler- Un-expected state = %d\n", pAuthPolicyParse->state); + XML_StopParser(pAuthPolicyParse->p, XML_FALSE); + break; + } + + DbgTrace(2, "-AuthPolicyStartElementHandler- End\n", 0); +} + + +//++======================================================================= +static +CasaStatus +ConsumeElementData( + IN AuthPolicyParse *pAuthPolicyParse, + IN const XML_Char *s, + IN int len, + INOUT char **ppElementData, + INOUT int *pElementDataLen) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus = CASA_STATUS_SUCCESS; + + DbgTrace(3, "-ConsumeElementData- Start\n", 0); + + // Proceed based on whether or not we have already consumed data + // for this element. + if (*ppElementData == NULL) + { + // We have not yet consumed data for this element + pAuthPolicyParse->elementDataProcessed = len; + + // Allocate a buffer to hold this element data (null terminated). + *ppElementData = (char*) malloc(len + 1); + if (*ppElementData) + { + memset(*ppElementData, 0, len + 1); + memcpy(*ppElementData, s, len); + + // Return the length of the element data buffer + *pElementDataLen = pAuthPolicyParse->elementDataProcessed + 1; + } + else + { + DbgTrace(0, "-ConsumeElementData- Buffer allocation failure\n", 0); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + } + else + { + char *pNewBuf; + + // We have already received token data, append this data to it. + pNewBuf = (char*) malloc(pAuthPolicyParse->elementDataProcessed + len + 1); + if (pNewBuf) + { + memset(pNewBuf, + 0, + pAuthPolicyParse->elementDataProcessed + len + 1); + memcpy(pNewBuf, + *ppElementData, + pAuthPolicyParse->elementDataProcessed); + memcpy(pNewBuf + pAuthPolicyParse->elementDataProcessed, s, len); + pAuthPolicyParse->elementDataProcessed += len; + + // Swap the buffers + free(*ppElementData); + *ppElementData = pNewBuf; + + // Return the length of the element data buffer + *pElementDataLen = pAuthPolicyParse->elementDataProcessed + 1; + } + else + { + DbgTrace(0, "-ConsumeElementData- Buffer allocation failure\n", 0); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + } + + DbgTrace(3, "-ConsumeElementData- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +static +void XMLCALL +AuthPolicyCharDataHandler( + IN AuthPolicyParse *pAuthPolicyParse, + IN const XML_Char *s, + IN int len) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + AuthContext *pAuthContext; + + DbgTrace(2, "-AuthPolicyCharDataHandler- Start\n", 0); + + // Just exit if being called to process white space + if (*s == '\n' || *s == '\r' || *s == '\t' || *s == ' ') + { + goto exit; + } + + // Proceed based on the state + switch (pAuthPolicyParse->state) + { + case AWAITING_REALM_DATA: + + // Get access to the AuthContext at the tail of the list + pAuthContext = CONTAINING_RECORD(pAuthPolicyParse->pAuthPolicy->authContextListHead.Blink, + AuthContext, + listEntry); + + // Consume the data + pAuthPolicyParse->status = ConsumeElementData(pAuthPolicyParse, + s, + len, + &pAuthContext->pContext, + &pAuthContext->contextLen); + if (CASA_SUCCESS(pAuthPolicyParse->status)) + { + // Advanced to the next state + pAuthPolicyParse->state = AWAITING_REALM_ELEMENT_END; + } + else + { + XML_StopParser(pAuthPolicyParse->p, XML_FALSE); + } + break; + + case AWAITING_MECHANISM_DATA: + case AWAITING_MECHANISM_ELEMENT_END: + + // Get access to the AuthContext at the tail of the list + pAuthContext = CONTAINING_RECORD(pAuthPolicyParse->pAuthPolicy->authContextListHead.Blink, + AuthContext, + listEntry); + + // Consume the data + pAuthPolicyParse->status = ConsumeElementData(pAuthPolicyParse, + s, + len, + &pAuthContext->pMechanism, + &pAuthContext->mechanismLen); + if (CASA_SUCCESS(pAuthPolicyParse->status)) + { + // Advanced to the next state + pAuthPolicyParse->state = AWAITING_MECHANISM_ELEMENT_END; + } + else + { + XML_StopParser(pAuthPolicyParse->p, XML_FALSE); + } + break; + + case AWAITING_MECHANISM_INFO_DATA: + case AWAITING_MECHANISM_INFO_ELEMENT_END: + + // Get access to the AuthContext at the tail of the list + pAuthContext = CONTAINING_RECORD(pAuthPolicyParse->pAuthPolicy->authContextListHead.Blink, + AuthContext, + listEntry); + + // Consume the data + pAuthPolicyParse->status = ConsumeElementData(pAuthPolicyParse, + s, + len, + &pAuthContext->pMechInfo, + &pAuthContext->mechInfoLen); + if (CASA_SUCCESS(pAuthPolicyParse->status)) + { + // Advanced to the next state + pAuthPolicyParse->state = AWAITING_MECHANISM_INFO_ELEMENT_END; + } + else + { + XML_StopParser(pAuthPolicyParse->p, XML_FALSE); + } + break; + + case AWAITING_UNKNOWN_DATA: + case AWAITING_UNKNOWN_ELEMENT_END: + + // Just advance the state + pAuthPolicyParse->state = AWAITING_UNKNOWN_ELEMENT_END; + break; + + default: + DbgTrace(0, "-AuthPolicyCharDataHandler- Un-expected state = %d\n", pAuthPolicyParse->state); + XML_StopParser(pAuthPolicyParse->p, XML_FALSE); + break; + } + +exit: + + DbgTrace(2, "-AuthPolicyCharDataHandler- End\n", 0); +} + + +//++======================================================================= +static +void XMLCALL +AuthPolicyEndElementHandler( + IN AuthPolicyParse *pAuthPolicyParse, + IN const XML_Char *name) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + AuthContext *pAuthContext; + + DbgTrace(2, "-AuthPolicyEndElementHandler- Start\n", 0); + + // Proceed based on the state + switch (pAuthPolicyParse->state) + { + case AWAITING_ROOT_ELEMENT_END: + + // In this state, we are only expecting the Authentication + // Policy Element. + if (strcmp(name, AUTH_POLICY_ELEMENT_NAME) == 0) + { + // Done. + pAuthPolicyParse->state = DONE_PARSING; + } + else + { + DbgTrace(0, "-AuthPolicyEndElementHandler- Un-expected end element\n", 0); + XML_StopParser(pAuthPolicyParse->p, XML_FALSE); + } + break; + + case AWAITING_AUTH_SOURCE_CHILD_START: + + // In this state, we are only expecting the Authentication + // Source Response Element. + if (strcmp(name, AUTH_SOURCE_ELEMENT_NAME) == 0) + { + // Good, advance to the next state. + pAuthPolicyParse->state = AWAITING_ROOT_ELEMENT_END; + } + else + { + DbgTrace(0, "-AuthPolicyEndHandler- Un-expected end element\n", 0); + XML_StopParser(pAuthPolicyParse->p, XML_FALSE); + } + break; + + case AWAITING_REALM_ELEMENT_END: + + // In this state, we are only expecting the Realm Element. + if (strcmp(name, REALM_ELEMENT_NAME) == 0) + { + // Good, advance to the next state. + pAuthPolicyParse->state = AWAITING_AUTH_SOURCE_CHILD_START; + } + else + { + DbgTrace(0, "-AuthPolicyEndElementHandler- Un-expected end element\n", 0); + XML_StopParser(pAuthPolicyParse->p, XML_FALSE); + } + break; + + case AWAITING_MECHANISM_ELEMENT_END: + + // In this state, we are only expecting the Mechanism Element. + if (strcmp(name, MECHANISM_ELEMENT_NAME) == 0) + { + // Good, advance to the next state. + pAuthPolicyParse->state = AWAITING_AUTH_SOURCE_CHILD_START; + } + else + { + DbgTrace(0, "-AuthPolicyEndElementHandler- Un-expected end element\n", 0); + XML_StopParser(pAuthPolicyParse->p, XML_FALSE); + } + break; + + case AWAITING_MECHANISM_INFO_DATA: + + // Get access to the AuthContext at the tail of the list + pAuthContext = CONTAINING_RECORD(pAuthPolicyParse->pAuthPolicy->authContextListHead.Blink, + AuthContext, + listEntry); + + // There was no mechanism info data. Set it to an empty string. + pAuthContext->pMechInfo = (char*) malloc(1); + if (pAuthContext->pMechInfo) + { + *pAuthContext->pMechInfo = '\0'; + } + else + { + DbgTrace(0, "-AuthPolicyEndElementHandler- Buffer allocation failure\n", 0); + pAuthPolicyParse->status = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + XML_StopParser(pAuthPolicyParse->p, XML_FALSE); + break; + } + // Fall through + + case AWAITING_MECHANISM_INFO_ELEMENT_END: + + // In this state, we are only expecting the Mechanism Info Element. + if (strcmp(name, MECHANISM_INFO_ELEMENT_NAME) == 0) + { + // Good, advance to the next state. + pAuthPolicyParse->state = AWAITING_AUTH_SOURCE_CHILD_START; + } + else + { + DbgTrace(0, "-AuthPolicyEndElementHandler- Un-expected end element\n", 0); + XML_StopParser(pAuthPolicyParse->p, XML_FALSE); + } + break; + + case AWAITING_UNKNOWN_ELEMENT_END: + + // Advance to the next state. + pAuthPolicyParse->state = AWAITING_AUTH_SOURCE_CHILD_START; + break; + + default: + DbgTrace(0, "-AuthPolicyEndElementHandler- Un-expected state = %d\n", pAuthPolicyParse->state); + XML_StopParser(pAuthPolicyParse->p, XML_FALSE); + break; + } + + DbgTrace(2, "-AuthPolicyEndElementHandler- End\n", 0); +} + + +//++======================================================================= +CasaStatus +CreateAuthPolicy( + IN char *pEncodedData, + IN int encodedDataLen, + INOUT AuthPolicy **ppAuthPolicy) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus; + AuthPolicy *pAuthPolicy = NULL; + AuthPolicyParse authPolicyParse = {0}; + char *pData = NULL; + int dataLen = 0; + + DbgTrace(1, "-CreateAuthPolicy- Start\n", 0); + + /* + * An authentication policy document has the following format: + * + * + * + * + * realm name + * authentication mechanism type + * authentication mechanism context data + * + * ... + * + * + * The authentication policy document can contain multiple auth_source + * elements. These auth_source elements can be for different authentication + * sources or for the same authentication source but specifying a different + * authentication mechanism. The mechanism_info element is optional. + * + * The following is a sample authentication policy document: + * + * + * + * + * Corp_eDirTree + * Krb5Authenticate + * host/hostname + * + * + * Corp_eDirTree + * PwdAuthenticate + * + * + * + * + * This authentication policy would tell the CASA client that it can + * authenticate to the CASA Authentication Token Service using + * credentials for the Corp_eDirTree and utilizing either the + * Krb5 authentication mechanism or the Pwd authentication mechanism. + * The Krb5 authentication mechanism context data specifies the + * name of the Kerberos service principal. + * + */ + + // Initialize output parameter + *ppAuthPolicy = NULL; + + // Decode the data + retStatus = DecodeData(pEncodedData, + encodedDataLen, + (void**) &pData, + &dataLen); + if (CASA_SUCCESS(retStatus)) + { + // Allocate space for the AuthPolicy structure + pAuthPolicy = (AuthPolicy*) malloc(sizeof(*pAuthPolicy)); + if (pAuthPolicy) + { + XML_Parser p; + + // Initialize the AuthPolicy object + memset(pAuthPolicy, 0, sizeof(*pAuthPolicy)); + InitializeListHead(&pAuthPolicy->authContextListHead); + + // Set the AuthPolicy object in the parse object + authPolicyParse.pAuthPolicy = pAuthPolicy; + + // Create parser + p = XML_ParserCreate(NULL); + if (p) + { + // Keep track of the parser in our parse object + authPolicyParse.p = p; + + // Initialize the status within the parse object + authPolicyParse.status = CASA_STATUS_SUCCESS; + + // Set the start and end element handlers + XML_SetElementHandler(p, + (XML_StartElementHandler) AuthPolicyStartElementHandler, + (XML_EndElementHandler) AuthPolicyEndElementHandler); + + // Set the character data handler + XML_SetCharacterDataHandler(p, (XML_CharacterDataHandler) AuthPolicyCharDataHandler); + + // Set our user data + XML_SetUserData(p, &authPolicyParse); + + // Parse the document + if (XML_Parse(p, pData, dataLen, 1) == XML_STATUS_OK) + { + // Verify that the parse operation completed successfully + if (authPolicyParse.state == DONE_PARSING) + { + // The parse operation succeded + retStatus = CASA_STATUS_SUCCESS; + } + else + { + DbgTrace(0, "-CreateAuthPolicy- Parse operation did not complete\n", 0); + + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_PROTOCOL_ERROR); + } + } + else + { + DbgTrace(0, "-CreateAuthPolicy- Parse error %d\n", XML_GetErrorCode(p)); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_PROTOCOL_ERROR); + } + + // Free the parser + XML_ParserFree(p); + } + else + { + DbgTrace(0, "-CreateAuthPolicy- Parser creation error\n", 0); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + + // Return the AuthPolicy object to the caller if necessary + if (CASA_SUCCESS(retStatus)) + { + *ppAuthPolicy = pAuthPolicy; + + // Forget about the AuthPolicy object so that it is not release down below + pAuthPolicy = NULL; + } + } + else + { + DbgTrace(0, "-CreateAuthPolicy- Buffer allocation error\n", 0); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + } + else + { + DbgTrace(0, "-CreateAuthPolicy- Buffer allocation error\n", 0); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + + // Release necessary allocated resources + if (pAuthPolicy) + RelAuthPolicy(pAuthPolicy); + + if (pData) + free(pData); + + DbgTrace(1, "-CreateAuthPolicy- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +void +RelAuthPolicy( + IN AuthPolicy *pAuthPolicy) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + LIST_ENTRY *pListEntry; + + DbgTrace(1, "-RelAuthPolicy- Start\n", 0); + + // Free all of the associated AuthContexts + pListEntry = pAuthPolicy->authContextListHead.Flink; + while (pListEntry != &pAuthPolicy->authContextListHead) + { + AuthContext *pAuthContext; + + // Get pointer to AuthContext structure + pAuthContext = CONTAINING_RECORD(pListEntry, AuthContext, listEntry); + + // Free associated buffers + if (pAuthContext->pContext) + free(pAuthContext->pContext); + + if (pAuthContext->pMechanism) + free(pAuthContext->pMechanism); + + if (pAuthContext->pMechInfo) + free(pAuthContext->pMechInfo); + + // Remove the entry from the list + RemoveEntryList(&pAuthContext->listEntry); + + // Free the AuthContext + free(pAuthContext); + + // Advance to the next entry + pListEntry = pAuthPolicy->authContextListHead.Flink; + } + + // Free the AuthPolicy + free(pAuthPolicy); + + DbgTrace(1, "-RelAuthPolicy- End\n", 0); +} + + +//++======================================================================= +//++======================================================================= +//++======================================================================= + diff --git a/CASA-auth-token/client/core/cache.c b/CASA-auth-token/client/core/cache.c new file mode 100644 index 00000000..d6bee9a2 --- /dev/null +++ b/CASA-auth-token/client/core/cache.c @@ -0,0 +1,588 @@ +/*********************************************************************** + * + * 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 + * + ***********************************************************************/ + + +//===[ Include files ]===================================================== + +#include "internal.h" +#include + +//===[ Type definitions ]================================================== + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + +HANDLE g_hCASAContext; + + +//++======================================================================= +AuthCacheEntry* +CreateAuthTokenCacheEntry( + IN const char *pCacheKey, + IN const char *pGroupOrHostName, + IN CasaStatus status, + IN char *pToken, + IN int entryLifetime, // seconds (0 == Lives forever) + IN void *pCredStoreScope + ) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus; + SSCS_KEYCHAIN_ID_T sessionKeyChain = {26, "SSCS_SESSION_KEY_CHAIN_ID"}; + SSCS_SECRET_ID_T sharedId = {27, "CASA_AUTHENTICATION_TOKENS"}; + int32_t tokenSize, entrySize, keySize; + AuthCacheEntry *pEntry = NULL; + char *pKey; + + DbgTrace(1, "-CreateAuthTokenCacheEntry- Start\n", 0); + + if (status == CASA_STATUS_SUCCESS) + { + tokenSize = (uint32_t) strlen(pToken); + } + else + { + tokenSize = 0; + } + + entrySize = tokenSize + sizeof(AuthCacheEntry); + + // Allocate space for the entry + // The AuthCacheEntry structure contains room for the tokens NULL terminator + pEntry = (AuthCacheEntry*) malloc(entrySize); + if (pEntry) + { + // Set the status + pEntry->status = status; + + if (pEntry->status == CASA_STATUS_SUCCESS) + { + memcpy(&pEntry->token[0], pToken, tokenSize); + } + + pEntry->token[tokenSize] = '\0'; + + // Set the time when the entry was added to the cache + pEntry->creationTime = GetTickCount(); + + // First determine the time when the entry is due to expire + if (entryLifetime != 0) + { + pEntry->expirationTime = pEntry->creationTime + (entryLifetime * 1000); + pEntry->doesNotExpire = false; + } + else + { + // The entry does not expire + pEntry->expirationTime = 0; + pEntry->doesNotExpire = true; + } + + keySize = (uint32_t)strlen(pCacheKey) + (uint32_t)strlen(pGroupOrHostName) + 2; + + pKey = malloc(keySize); + + if (pKey) + { + strncpy(pKey, pCacheKey, keySize); + strncat(pKey, "@", keySize); + strncat(pKey, pGroupOrHostName, keySize); + + retStatus = miCASAWriteBinaryKey(g_hCASAContext, + 0, + &sessionKeyChain, + &sharedId, + (SS_UTF8_T*) pKey, + keySize, + (uint8_t *) pEntry, + (uint32_t*) &entrySize, + NULL, + (SSCS_EXT_T*) pCredStoreScope); + + + free(pKey); + } + else + { + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + } + else + { + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + + DbgTrace(1, "-CreateAuthTokenCacheEntry- End, pEntry = %0lX\n", (long) pEntry); + + return pEntry; +} + + +//++======================================================================= +AuthCacheEntry* +CreateSessionTokenCacheEntry( + IN const char *pCacheKey, + IN CasaStatus status, + IN char *pToken, + IN int entryLifetime, // seconds (0 == Lives forever) + IN void *pCredStoreScope + ) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus; + SSCS_KEYCHAIN_ID_T sessionKeyChain = {26, "SSCS_SESSION_KEY_CHAIN_ID"}; + SSCS_SECRET_ID_T sharedId = {20, "CASA_SESSION_TOKENS"}; + int32_t tokenSize, entrySize; + AuthCacheEntry *pEntry = NULL; + + DbgTrace(1, "-CreateSessionTokenCacheEntry- Start\n", 0); + + if (status == CASA_STATUS_SUCCESS) + { + tokenSize = (uint32_t)strlen(pToken); + } + else + { + tokenSize = 0; + } + + entrySize = tokenSize + sizeof(AuthCacheEntry); + + // Allocate space for the entry + // The AuthCacheEntry structure contains room for the tokens NULL terminator + pEntry = (AuthCacheEntry*) malloc(entrySize); + if (pEntry) + { + // Set the status + pEntry->status = status; + + if (pEntry->status == CASA_STATUS_SUCCESS) + { + memcpy(&pEntry->token[0], pToken, tokenSize); + } + + pEntry->token[tokenSize] = '\0'; + + // Set the time when the entry was added to the cache + pEntry->creationTime = GetTickCount(); + + // First determine the time when the entry is due to expire + if (entryLifetime != 0) + { + pEntry->expirationTime = pEntry->creationTime + (entryLifetime * 1000); + pEntry->doesNotExpire = false; + } + else + { + // The entry does not expire + pEntry->expirationTime = 0; + pEntry->doesNotExpire = true; + } + + retStatus = miCASAWriteBinaryKey(g_hCASAContext, + 0, + &sessionKeyChain, + &sharedId, + (SS_UTF8_T*) pCacheKey, + (uint32_t) strlen(pCacheKey) + 1, + (uint8_t *) pEntry, + (uint32_t*) &entrySize, + NULL, + (SSCS_EXT_T*) pCredStoreScope); + } + else + { + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + + DbgTrace(1, "-CreateSessionTokenCacheEntry- End, pEntry = %0lX\n", (long) pEntry); + + return pEntry; +} + + +//++======================================================================= +void +FreeAuthCacheEntry( + IN AuthCacheEntry *pEntry + ) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + DbgTrace(1, "-FreeAuthCacheEntry- Start, pEntry = %0lX\n", (long) pEntry); + + // Free the entry + free(pEntry); + + DbgTrace(1, "-FreeAuthCacheEntry- End\n", 0); +} + + +//++======================================================================= +static +bool +CacheEntryLifetimeExpired( + IN DWORD creationTime, + IN DWORD expirationTime + ) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + DWORD currentTime = GetTickCount(); + bool expired = false; + + DbgTrace(2, "-CacheEntryLifetimeExpired- Start\n", 0); + + // Check if the clock has wrapped + if (currentTime >= creationTime) + { + // The clock has not wrapped, check if the + // expiration time has wrapped. + if (expirationTime > creationTime) + { + // The expiration time also has not wrapped, + // do a straight compare against the current + // time. + if (currentTime >= expirationTime) + { + // It has expired + expired = true; + } + } + } + else + { + // The clock has wrapped, check if the expiration + // time also wrapped. + if (expirationTime > creationTime) + { + // The expiration time did not wrap, therefore + // it has been exceeded since the clock wrapped. + expired = true; + } + else + { + // The expiration time also wrapped, do a straight + // compare against the current time. + if (currentTime >= expirationTime) + { + // It has expired + expired = true; + } + } + } + + DbgTrace(2, "-CacheEntryLifetimeExpired- End, result = %08X\n", expired); + + return expired; +} + + +//++======================================================================= +AuthCacheEntry* +FindSessionTokenEntryInCache( + IN const char *pCacheKey, + IN void *pCredStoreScope + ) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus; + SSCS_KEYCHAIN_ID_T sessionKeyChain = {26, "SSCS_SESSION_KEY_CHAIN_ID"}; + SSCS_SECRET_ID_T sharedId = {20, "CASA_SESSION_TOKENS"}; + int32_t valueLength, bytesRequired; + AuthCacheEntry *pEntry = NULL; + + + DbgTrace(1, "-FindSessionTokenEntryInCache- Start\n", 0); + + valueLength = 0; + bytesRequired = 0; + + retStatus = miCASAReadBinaryKey(g_hCASAContext, + 0, + &sessionKeyChain, + &sharedId, + (SS_UTF8_T*) pCacheKey, + (uint32_t) strlen(pCacheKey) + 1, + NULL, + (uint32_t*) &valueLength, + (SSCS_PASSWORD_T*) NULL, + (uint32_t*) &bytesRequired, + (SSCS_EXT_T*) pCredStoreScope); + + if (retStatus == NSSCS_E_ENUM_BUFF_TOO_SHORT + && bytesRequired != 0) + { + pEntry = (AuthCacheEntry*) malloc(bytesRequired); + + if (pEntry) + { + valueLength = bytesRequired; + bytesRequired = 0; + + retStatus = miCASAReadBinaryKey(g_hCASAContext, + 0, + &sessionKeyChain, + &sharedId, + (SS_UTF8_T*) pCacheKey, + (uint32_t) strlen(pCacheKey) + 1, + (uint8_t *) pEntry, + (uint32_t*) &valueLength, + (SSCS_PASSWORD_T*) NULL, + (uint32_t*) &bytesRequired, + (SSCS_EXT_T*) pCredStoreScope); + if (CASA_SUCCESS(retStatus)) + { + if (pEntry->doesNotExpire == false + && CacheEntryLifetimeExpired(pEntry->creationTime, pEntry->expirationTime)) + { + // Remove the entry ??? + //miCASARemoveBinaryKey(); + + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_UNSUCCESSFUL); + } + } + + if (!CASA_SUCCESS(retStatus)) + { + FreeAuthCacheEntry(pEntry); + pEntry = NULL; + } + } + } + + DbgTrace(1, "-FindSessionTokenEntryInCache- End, pEntry = %0lX\n", (long) pEntry); + + return pEntry; +} + +//++======================================================================= +AuthCacheEntry* +FindAuthTokenEntryInCache( + IN const char *pCacheKey, + IN const char *pGroupOrHostName, + IN void *pCredStoreScope + ) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus; + SSCS_KEYCHAIN_ID_T sessionKeyChain = {26, "SSCS_SESSION_KEY_CHAIN_ID"}; + SSCS_SECRET_ID_T sharedId = {27, "CASA_AUTHENTICATION_TOKENS"}; + int32_t valueLength, bytesRequired, keySize; + AuthCacheEntry *pEntry = NULL; + char *pKey; + + + DbgTrace(1, "-FindAuthTokenEntryInCache- Start\n", 0); + + keySize = (uint32_t)strlen(pCacheKey) + (uint32_t)strlen(pGroupOrHostName) + 2; + + pKey = malloc(keySize); + if (pKey) + { + strncpy(pKey, pCacheKey, keySize); + strncat(pKey, "@", keySize); + strncat(pKey, pGroupOrHostName, keySize); + + valueLength = 0; + bytesRequired = 0; + + retStatus = miCASAReadBinaryKey(g_hCASAContext, + 0, + &sessionKeyChain, + &sharedId, + (SS_UTF8_T*) pKey, + keySize, + NULL, + (uint32_t*) &valueLength, + (SSCS_PASSWORD_T*) NULL, + (uint32_t*) &bytesRequired, + (SSCS_EXT_T*) pCredStoreScope); + + if (retStatus == NSSCS_E_ENUM_BUFF_TOO_SHORT + && bytesRequired != 0) + { + pEntry = (AuthCacheEntry*) malloc(bytesRequired); + + if (pEntry) + { + valueLength = bytesRequired; + bytesRequired = 0; + + retStatus = miCASAReadBinaryKey(g_hCASAContext, + 0, + &sessionKeyChain, + &sharedId, + (SS_UTF8_T*) pKey, + keySize, + (uint8_t *) pEntry, + (uint32_t*) &valueLength, + (SSCS_PASSWORD_T*) NULL, + (uint32_t*) &bytesRequired, + (SSCS_EXT_T*) pCredStoreScope); + if (CASA_SUCCESS(retStatus)) + { + if (pEntry->doesNotExpire == false + && CacheEntryLifetimeExpired(pEntry->creationTime, pEntry->expirationTime)) + { + // Remove the entry ??? + //miCASARemoveBinaryKey(); + + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_UNSUCCESSFUL); + } + } + + if (!CASA_SUCCESS(retStatus)) + { + FreeAuthCacheEntry(pEntry); + pEntry = NULL; + } + } + } + + free(pKey); + } + + DbgTrace(1, "-FindAuthTokenEntryInCache- End, pEntry = %0lX\n", (long) pEntry); + + return pEntry; +} + + +//++======================================================================= +CasaStatus +InitializeAuthCache() +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus; + SSCS_SECRETSTORE_T ssId; + + DbgTrace(1, "-InitializeAuthCache- Start\n", 0); + + ssId.version = NSSCS_VERSION_NUMBER; + strcpy((char *)ssId.ssName, (char *)SSCS_DEFAULT_SECRETSTORE_ID); + + g_hCASAContext = miCASAOpenSecretStoreCache(&ssId, + 0, + NULL); + if (!g_hCASAContext) + { + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_UNSUCCESSFUL); + } + else + { + retStatus = CASA_STATUS_SUCCESS; + } + + DbgTrace(1, "-InitializeAuthCache- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +//++======================================================================= +//++======================================================================= + diff --git a/CASA-auth-token/client/core/client.conf b/CASA-auth-token/client/core/client.conf new file mode 100644 index 00000000..46c0d85f --- /dev/null +++ b/CASA-auth-token/client/core/client.conf @@ -0,0 +1,88 @@ +####################################################### +# # +# CASA Authentication Token System configuration file # +# for client. # +# # +####################################################### + +# +# ATS-hostname setting. +# +# Description: Used to configure the address of the +# ATS that should be used for obtaining +# authentication tokens. +# +# If this parameter is not set, the client +# assummes that the ATS resides in the same +# host as the authentication token consuming +# services. +# +#ATS-hostname hostname or IP address + +# +# ATS-port setting. +# +# Description: Used to configure the port utilized by the +# ATS to listen for connections. +# +# If this parameter is not set .... +# +#ATS-port 2645 + +# +# DisableSecureConnections setting. +# +# Description: Used to disable the use of secure connections (SSL) between +# the Client and ATSs. +# +# If this parameter is not set to true, the client +# defaults to communicating securedly with ATSs. +# +# Security Note: Disabling secure connections allows +# malicious users/processes to view confidential +# information such as username/passwords and to tamper +# with client-ATS communications without being detected. +# You should not disable secure connections unless you are +# trying to debug the authentication token infrastructure. +# +#DisableSecureConnections false + +# +# AllowInvalidCerts setting. +# +# Description: Used to specify that the client should ignore +# invalid certificates presented by ATSs when +# performing SSL communications. +# +# If this parameter is not set to true, the client defaults +# to not ignoring invalid certificates presented by ATSs. +# ATSs. +# +# Security Note: Ignoring invalid certificates downgrades the +# security of your infrastructure by allowing a malicious +# process to impersonate an ATS and obtain information that +# is confidential such as username and passwords. +# +AllowInvalidCerts true + +# +# UsersCannotAllowInvalidCerts setting. +# +# Description: Used to specify that the client should not allow users to +# decide that invalid certificates presented by ATSs should be +# ignored. +# +# If this parameter is not set to true, the client defaults +# to allow users to choose whether or not invalid certificates +# presented by ATSs. +# +# If this parameter is set to true then users are not consulted +# when an invalid server certificate is received and communications +# between the client and the ATS fail. +# +# Note: This parameter has no effect if the setting AllowInvalidCerts +# is set to true. +# +# THIS FUNCTIONALITY HAS NOT BEEN IMPLEMENTED +# +#UsersCannotAllowInvalidCerts true diff --git a/CASA-auth-token/client/core/config.c b/CASA-auth-token/client/core/config.c new file mode 100644 index 00000000..f3680313 --- /dev/null +++ b/CASA-auth-token/client/core/config.c @@ -0,0 +1,686 @@ +/*********************************************************************** + * + * 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 + * + ***********************************************************************/ + + +//===[ Include files ]===================================================== + +#include "internal.h" + +//===[ Type definitions ]================================================== + +// +// Config Key object +// +typedef struct _ConfigKey +{ + LIST_ENTRY listEntry; + char *pKeyName; + int keyNameLen; + char *pValue; + int valueLen; + +} ConfigKey, *pConfigKey; + +// +// Config Interface instance data +// +typedef struct _ConfigIfInstance +{ + LIST_ENTRY listEntry; + int refCount; + char *pConfigFolder; + int configFolderLen; + char *pConfigName; + int configNameLen; + LIST_ENTRY configKeyListHead; + ConfigIf configIf; + +} ConfigIfInstance, *PConfigIfInstance; + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + +// ConfigIf variables +static +LIST_ENTRY g_configIfListHead = {&g_configIfListHead, &g_configIfListHead}; + +static +int g_numConfigIfObjs = 0; + + +//++======================================================================= +static void +RemoveWhiteSpaceFromTheEnd( + IN const char *pInString) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + char *pLineEnd = (char*) pInString + strlen(pInString) - 1; + + + DbgTrace(3, "-RemoveWhiteSpaceFromTheEnd- Start\n", 0); + + while (pLineEnd != pInString) + { + if (*pLineEnd == '\n' + || *pLineEnd == ' ' + || *pLineEnd == '\t') + { + // Strike this character + *pLineEnd = '\0'; + pLineEnd --; + } + else + { + // Found a non-white character + break; + } + } + + DbgTrace(3, "-RemoveWhiteSpaceFromTheEnd- End\n", 0); +} + + +//++======================================================================= +static char* +SkipWhiteSpace( + IN const char *pInString) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + char *pOutString = (char*) pInString; + + DbgTrace(3, "-SkipWhiteSpace- Start\n", 0); + + while (*pOutString != '\0') + { + if (*pOutString == '\n' + || *pOutString == ' ' + || *pOutString == '\t') + { + // Skip this character + pOutString ++; + } + else + { + // Found a non-white character + break; + } + } + + DbgTrace(3, "-SkipWhiteSpace- End\n", 0); + + return pOutString; +} + + +//++======================================================================= +static char* +SkipNonWhiteSpace( + IN const char *pInString) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + char *pOutString = (char*) pInString; + + DbgTrace(3, "-SkipNonWhiteSpace- Start\n", 0); + + while (*pOutString != '\0') + { + if (*pOutString == '\n' + || *pOutString == ' ' + || *pOutString == '\t') + { + // Found a white character + break; + } + else + { + // Skip this character + pOutString ++; + } + } + + DbgTrace(3, "-SkipNonWhiteSpace- End\n", 0); + + return pOutString; +} + + +//++======================================================================= +static void +LowerCaseString( + IN char *pDestString, + IN const char *pSrcString) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + int i; + + DbgTrace(3, "-LowerCaseString- Start\n", 0); + + // Copy the string as lower case + for (i = 0; pSrcString[i] != '\0'; i++) + { + if (isalpha(pSrcString[i])) + pDestString[i] = tolower(pSrcString[i]); + else + pDestString[i] = pSrcString[i]; + } + + // Null terminate the destination string + pDestString[i] = '\0'; + + DbgTrace(3, "-LowerCaseString- End\n", 0); +} + + +//++======================================================================= +int SSCS_CALL +ConfigIf_AddReference( + IN const void *pIfInstance) +// +// Arguments: +// pIfInstance - +// Pointer to interface object. +// +// Returns: +// Interface reference count. +// +// Description: +// Increases interface reference count. +// +// L2 +//=======================================================================-- +{ + int refCount; + ConfigIfInstance *pConfigIfInstance = CONTAINING_RECORD(pIfInstance, ConfigIfInstance, configIf); + + DbgTrace(2, "-ConfigIf_AddReference- Start\n", 0); + + // Increment the reference count on the object + pConfigIfInstance->refCount ++; + refCount = pConfigIfInstance->refCount; + + DbgTrace(2, "-ConfigIf_AddReference- End, refCount = %08X\n", refCount); + + return refCount; +} + + +//++======================================================================= +void SSCS_CALL +ConfigIf_ReleaseReference( + IN const void *pIfInstance) +// +// Arguments: +// pIfInstance - +// Pointer to interface object. +// +// Returns: +// Nothing. +// +// Description: +// Decreases interface reference count. The interface is deallocated if +// the reference count becomes zero. +// +// L2 +//=======================================================================-- +{ + bool freeObj = false; + ConfigIfInstance *pConfigIfInstance = CONTAINING_RECORD(pIfInstance, ConfigIfInstance, configIf); + + DbgTrace(2, "-ConfigIf_ReleaseReference- Start\n", 0); + + // Decrement the reference count on the object and determine if it needs to + // be released. + pConfigIfInstance->refCount --; + if (pConfigIfInstance->refCount == 0) + { + // The object needs to be released, forget about it. + freeObj = true; + g_numConfigIfObjs --; + RemoveEntryList(&pConfigIfInstance->listEntry); + } + + // Free object if necessary + if (freeObj) + { + // Free all of the config key objects associated with this configuration + // interface instance. + while (!IsListEmpty(&pConfigIfInstance->configKeyListHead)) + { + LIST_ENTRY *pListEntry; + ConfigKey *pConfigKey; + + // Get reference to entry at the head of the list + pListEntry = pConfigIfInstance->configKeyListHead.Flink; + pConfigKey = CONTAINING_RECORD(pListEntry, ConfigKey, listEntry); + + // Free the buffers associated with the ConfigKey + free(pConfigKey->pKeyName); + free(pConfigKey->pValue); + + // Remove the entry from the list + RemoveEntryList(&pConfigKey->listEntry); + + // Finish freeing the ConfigKey + free(pConfigKey); + } + + // Free the rest of the buffers associated with the interface instance data + free(pConfigIfInstance->pConfigFolder); + free(pConfigIfInstance->pConfigName); + free(pConfigIfInstance); + } + + DbgTrace(2, "-ConfigIf_ReleaseReference- End\n", 0); +} + + +//++======================================================================= +char* SSCS_CALL +ConfigIf_GetEntryValue( + IN const void *pIfInstance, + IN const char *pKeyName) +// +// Arguments: +// pIfInstance - +// Pointer to interface object. +// +// pKeyName - +// Pointer to NULL terminated string that contains the +// name of the key whose value is being requested. +// +// Returns: +// Pointer to NULL terminated string with value being requested or NULL. +// +// Description: +// Gets value associated with a key for the configuration object. +// +// L2 +//=======================================================================-- +{ + ConfigIfInstance *pConfigIfInstance = CONTAINING_RECORD(pIfInstance, ConfigIfInstance, configIf); + char *pValue = NULL; + LIST_ENTRY *pListEntry; + ConfigKey *pConfigKey; + int keyNameLen = (int) strlen(pKeyName); + char *pKeyNameLowercase; + + DbgTrace(2, "-ConfigIf_GetEntryValue- Start\n", 0); + + // Allocate enough space to hold lower case version of the key name + pKeyNameLowercase = (char*) malloc(keyNameLen + 1); + if (pKeyNameLowercase) + { + // Lower case the key name + LowerCaseString(pKeyNameLowercase, pKeyName); + + // Try to find matching ConfigKey + pListEntry = pConfigIfInstance->configKeyListHead.Flink; + while (pListEntry != &pConfigIfInstance->configKeyListHead) + { + // Get pointer to the current entry + pConfigKey = CONTAINING_RECORD(pListEntry, ConfigKey, listEntry); + + // Check if we have a match + if (pConfigKey->keyNameLen == keyNameLen + && memcmp(pKeyNameLowercase, pConfigKey->pKeyName, keyNameLen) == 0) + { + // We found it, return its value. + pValue = (char*) malloc(pConfigKey->valueLen + 1); + if (pValue) + { + strcpy(pValue, pConfigKey->pValue); + } + else + { + DbgTrace(0, "-ConfigIf_GetEntryValue- Buffer allocation failure\n", 0); + } + break; + } + + // Advance to the next entry + pListEntry = pListEntry->Flink; + } + + // Free the lower case version of the key name + free(pKeyNameLowercase); + } + else + { + DbgTrace(0, "-ConfigIf_GetEntryValue- Buffer allocation failure\n", 0); + } + + DbgTrace(2, "-ConfigIf_GetEntryValue- End, pValue = %08X\n", (unsigned int) pValue); + + return pValue; +} + + + +//++======================================================================= +CasaStatus +GetConfigInterface( + IN const char *pConfigFolder, + IN const char *pConfigName, + INOUT ConfigIf **ppConfigIf) +// +// Arguments: +// pConfigFolder - +// Pointer to NULL terminated string that contains the name of +// the folder containing the configuration file. +// +// pConfigName - +// Pointer to NULL terminated string containing the name of the +// configuration entry. +// +// ppConfigIf - +// Pointer to variable that will receive pointer to ConfigIf +// instance. +// +// Returns: +// Casa Status +// +// Description: +// Get configuration interface to specified configuration entry. +// +// L2 +//=======================================================================-- +{ + int configFolderLen = (int) strlen(pConfigFolder); + int configNameLen = (int)strlen(pConfigName); + ConfigIfInstance *pConfigIfInstance; + LIST_ENTRY *pListEntry; + CasaStatus retStatus = CasaStatusBuild(CASA_SEVERITY_INFORMATIONAL, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_OBJECT_NOT_FOUND); + + DbgTrace(2, "-GetConfigInterface- Start\n", 0); + + // Check if we already have an entry in our list for the configuration + pListEntry = g_configIfListHead.Flink; + while (pListEntry != &g_configIfListHead) + { + // Get pointer to the current entry + pConfigIfInstance = CONTAINING_RECORD(pListEntry, ConfigIfInstance, listEntry); + + // Check if we have a match + if (pConfigIfInstance->configFolderLen == configFolderLen + && pConfigIfInstance->configNameLen == configNameLen + && memcmp(pConfigFolder, pConfigIfInstance->pConfigFolder, configFolderLen) == 0 + && memcmp(pConfigName, pConfigIfInstance->pConfigName, configNameLen) == 0) + { + // We found it, return the ConfigIf associated with the instance data + // after incrementing its reference count. + pConfigIfInstance->refCount ++; + *ppConfigIf = &pConfigIfInstance->configIf; + + // Success + retStatus = CASA_STATUS_SUCCESS; + break; + } + + // Advance to the next entry + pListEntry = pListEntry->Flink; + } + + // Proceed to create interface instance data for the configuration if none was found + if (retStatus != CASA_STATUS_SUCCESS) + { + char *pFilePath; + + // Build a string containing the configuration file path + pFilePath = (char*) malloc(configFolderLen + 1 + configNameLen + sizeof(".conf")); + if (pFilePath) + { + FILE *pConfigFile; + + strcpy(pFilePath, pConfigFolder); + strcat(pFilePath, pathCharString); + strcat(pFilePath, pConfigName); + strcat(pFilePath, ".conf"); + + // Open the configuration file for reading + pConfigFile = fopen(pFilePath, "r"); + if (pConfigFile) + { + // Opened the file, create a ConfigIfInstance object for it. + pConfigIfInstance = (ConfigIfInstance*) malloc(sizeof(*pConfigIfInstance)); + if (pConfigIfInstance) + { + // Initialize the list head within the instance data + InitializeListHead(&pConfigIfInstance->configKeyListHead); + + // Initialize the ConfigIf within the instance data + pConfigIfInstance->configIf.addReference = ConfigIf_AddReference; + pConfigIfInstance->configIf.releaseReference = ConfigIf_ReleaseReference; + pConfigIfInstance->configIf.getEntryValue = ConfigIf_GetEntryValue; + + // Save the ConfigFolder and ConfigName information within the instance data + pConfigIfInstance->pConfigFolder = (char*) malloc(configFolderLen + 1); + if (pConfigIfInstance->pConfigFolder) + { + strcpy(pConfigIfInstance->pConfigFolder, pConfigFolder); + pConfigIfInstance->configFolderLen = configFolderLen; + + pConfigIfInstance->pConfigName = (char*) malloc(configNameLen + 1); + if (pConfigIfInstance->pConfigName) + { + strcpy(pConfigIfInstance->pConfigName, pConfigName); + pConfigIfInstance->configNameLen = configNameLen; + + // Add the instance data into our list and bump up its reference count + // since we did that. + InsertTailList(&g_configIfListHead, &pConfigIfInstance->listEntry); + pConfigIfInstance->refCount = 1; + + // At this point we want to return success to the caller even if we + // experience a read error. + retStatus = CASA_STATUS_SUCCESS; + + // Return the ConfigIf associated with the instance data after + // incrementing its reference count. + pConfigIfInstance->refCount ++; + *ppConfigIf = &pConfigIfInstance->configIf; + + // Now update the instance data with the information present in the file + if (fseek(pConfigFile, 0, SEEK_SET) == 0) + { + char line[512]; + + while (fgets(line, sizeof(line), pConfigFile) != NULL) + { + int lineLength; + + RemoveWhiteSpaceFromTheEnd(line); + + lineLength = (int) strlen(line); + if (lineLength != 0) + { + char *pKey; + char *pKeyEnd; + char *pValue; + ConfigKey *pConfigKey; + + // Attempt to find the key + pKey = SkipWhiteSpace(line); + + // Make sure that we are not dealing with an empty line or a comment + if (*pKey == '\0' || *pKey == '#') + continue; + + // Go past the key + pKeyEnd = SkipNonWhiteSpace(pKey); + + // Protect against a malformed line + if (*pKeyEnd == '\0') + { + DbgTrace(0, "-GetConfigInterface- Key found without value\n", 0); + continue; + } + + // Attempt to find the value + pValue = SkipWhiteSpace(pKeyEnd); + + // Protect against a malformed line + if (*pValue == '\0') + { + DbgTrace(0, "-GetConfigInterface- Key found without value\n", 0); + continue; + } + + // Delineate the key + *pKeyEnd = '\0'; + + // Create a ConfigKey object for this key/value pair + pConfigKey = (ConfigKey*) malloc(sizeof(*pConfigKey)); + if (pConfigKey) + { + pConfigKey->keyNameLen = (int) strlen(pKey); + pConfigKey->pKeyName = (char*) malloc(pConfigKey->keyNameLen + 1); + if (pConfigKey->pKeyName) + { + // Save the key name in lower case + LowerCaseString(pConfigKey->pKeyName, pKey); + + pConfigKey->valueLen = (int) strlen(pValue); + pConfigKey->pValue = (char*) malloc(pConfigKey->valueLen + 1); + if (pConfigKey->pValue) + { + strcpy(pConfigKey->pValue, pValue); + + // The entry is ready, now associate it with the instance data. + InsertTailList(&pConfigIfInstance->configKeyListHead, &pConfigKey->listEntry); + } + else + { + DbgTrace(0, "-GetConfigInterface- Buffer allocation failure\n", 0); + free(pConfigKey->pKeyName); + free(pConfigKey); + } + } + else + { + DbgTrace(0, "-GetConfigInterface- Buffer allocation failure\n", 0); + free(pConfigKey); + } + } + else + { + DbgTrace(0, "-GetConfigInterface- Buffer allocation failure\n", 0); + } + } + } + } + else + { + DbgTrace(0, "-GetConfigInterface- File seek error, errno = %d\n", errno); + } + } + else + { + DbgTrace(0, "-GetConfigInterface- Buffer allocation failure\n", 0); + + // Free the buffers associated with the instance data + free(pConfigIfInstance->pConfigFolder); + free(pConfigIfInstance); + } + } + else + { + DbgTrace(0, "-GetConfigInterface- Buffer allocation failure\n", 0); + + // Free the buffer allocated for the instance data + free(pConfigIfInstance); + } + } + else + { + DbgTrace(0, "-GetConfigInterface- Buffer allocation failure\n", 0); + } + + // Close the file + fclose(pConfigFile); + } + else + { + DbgTrace(0, "-GetConfigInterface- Unable to open config file, errno = %d\n", errno); + DbgTrace(0, "-GetConfigInterface- Config file unable to open = %s\n", pFilePath); + } + } + else + { + DbgTrace(0, "-GetConfigInterface- Buffer allocation error\n", 0); + } + } + + DbgTrace(2, "-GetConfigInterface- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +//++======================================================================= +//++======================================================================= + diff --git a/CASA-auth-token/client/core/config_if.h b/CASA-auth-token/client/core/config_if.h new file mode 100644 index 00000000..0cdf31ce --- /dev/null +++ b/CASA-auth-token/client/core/config_if.h @@ -0,0 +1,120 @@ +/*********************************************************************** + * + * 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 + * + ***********************************************************************/ + + +#ifndef _CONFIG_IF_H_ +#define _CONFIG_IF_H_ + + +//===[ Include files ]===================================================== + +//===[ Type definitions ]================================================== + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + +/************************************************************************** +*************************************************************************** +** ** +** Configuration Object Interface Definitions ** +** ** +*************************************************************************** +**************************************************************************/ + + +//++======================================================================= +typedef +int +(SSCS_CALL *PFNConfiglIf_AddReference)( + IN const void *pIfInstance); +// +// Arguments: +// pIfInstance - +// Pointer to interface object. +// +// Returns: +// Interface reference count. +// +// Description: +// Increases interface reference count. +//=======================================================================-- + + +//++======================================================================= +typedef +void +(SSCS_CALL *PFNConfiglIf_ReleaseReference)( + IN const void *pIfInstance); +// +// Arguments: +// pIfInstance - +// Pointer to interface object. +// +// Returns: +// Nothing. +// +// Description: +// Decreases interface reference count. The interface is deallocated if +// the reference count becomes zero. +//=======================================================================-- + + +//++======================================================================= +typedef +char* +(SSCS_CALL *PFNConfiglIf_GetEntryValue)( + IN const void *pIfInstance, + IN const char *pKeyName); +// +// Arguments: +// pIfInstance - +// Pointer to interface object. +// +// pKeyName - +// Pointer to NULL terminated string that contains the +// name of the key whose value is being requested. +// +// Returns: +// Pointer to NULL terminated string with value being requested or NULL. +// +// Description: +// Gets value associated with a key for the configuration object. +//=======================================================================-- + + +// +// Config Interface Object +// +typedef struct _ConfigIf +{ + PFNConfiglIf_AddReference addReference; + PFNConfiglIf_ReleaseReference releaseReference; + PFNConfiglIf_GetEntryValue getEntryValue; + +} ConfigIf, *PConfigIf; + + +#endif // #ifndef _CONFIG_IF_H_ + diff --git a/CASA-auth-token/client/core/engine.c b/CASA-auth-token/client/core/engine.c new file mode 100644 index 00000000..a697f712 --- /dev/null +++ b/CASA-auth-token/client/core/engine.c @@ -0,0 +1,894 @@ +/*********************************************************************** + * + * 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 + * + ***********************************************************************/ + + +//===[ Include files ]===================================================== + +#include "internal.h" + +//===[ Type definitions ]================================================== + +#define DEFAULT_RETRY_LIFETIME 5 // seconds + +//===[ Function prototypes ]=============================================== + +int +InitializeLibrary(void); + +//===[ Global variables ]================================================== + +// +// Debug tracing level +// +int DebugLevel = 0; + +// +// Operating parameter +// +bool g_bInitialized = false; +long g_rpcFlags = SECURE_RPC_FLAG | ALLOW_INVALID_CERTS_USER_APPROVAL_RPC_FLAG; +char *g_pATSHostName = NULL; +uint16_t g_ATSPort = 2645; + + +//++======================================================================= +static +CasaStatus +ObtainSessionToken( + IN RpcSession *pRpcSession, + IN AuthPolicy *pAuthPolicy, + IN const char *pHostName, + IN void *pCredStoreScope, + INOUT char **ppSessionToken) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_UNSUCCESSFUL); + LIST_ENTRY *pListEntry; + AuthCacheEntry *pCacheEntry = NULL; + + DbgTrace(1, "-ObtainSessionToken- Start\n", 0); + + // Initialize output parameter + *ppSessionToken = NULL; + + // Look in our cache for an entry that matches one of the auth + // contexts specified in the AuthPolicy object. + pListEntry = pAuthPolicy->authContextListHead.Flink; + while (pListEntry != &pAuthPolicy->authContextListHead) + { + AuthContext *pAuthContext; + + // Get pointer to AuthContext structure + pAuthContext = CONTAINING_RECORD(pListEntry, AuthContext, listEntry); + + // Try to find a cache entry for the auth context + pCacheEntry = FindSessionTokenEntryInCache(pAuthContext->pContext, + pCredStoreScope); + if (pCacheEntry != NULL) + { + // Cache entry found, check if it is of use to us. + if (CASA_SUCCESS(pCacheEntry->status)) + { + // This entry can be used, stop looking. + retStatus = pCacheEntry->status; + break; + } + else + { + // Free the entry + FreeAuthCacheEntry(pCacheEntry); + } + } + + // Advance to the next entry + pListEntry = pListEntry->Flink; + } + + // If we did not find a cache entry that we can use, then try to create one. + pListEntry = pAuthPolicy->authContextListHead.Flink; + while (!CASA_SUCCESS(retStatus) + && pListEntry != &pAuthPolicy->authContextListHead) + { + AuthContext *pAuthContext; + char *pAuthMechToken; + + // Get pointer to AuthContext structure + pAuthContext = CONTAINING_RECORD(pListEntry, AuthContext, listEntry); + + // Only try to create cache entry for the auth context if there is not + // one already. + pCacheEntry = FindSessionTokenEntryInCache(pAuthContext->pContext, + pCredStoreScope); + if (pCacheEntry == NULL) + { + char *pReqMsg = NULL; + char *pRespMsg = NULL; + int respLen; + + // Get authentication mechanism token + retStatus = GetAuthMechToken(pAuthContext, + pHostName, + pCredStoreScope, + &pAuthMechToken); + if (!CASA_SUCCESS(retStatus)) + { + // We were not able to obtain an authentication mechanism token + // for the context. + // + // Advance to the next entry + pListEntry = pListEntry->Flink; + continue; + } + + // Authenticate to the ATS + pReqMsg = BuildAuthenticateMsg(pAuthContext, pAuthMechToken); + if (pReqMsg) + { + // Issue rpc + retStatus = Rpc(pRpcSession, + "Authenticate", + g_rpcFlags, + pReqMsg, + &pRespMsg, + &respLen); + if (CASA_SUCCESS(retStatus)) + { + AuthenticateResp *pAuthenticateResp; + + // Create Authenticate response object + retStatus = CreateAuthenticateResp(pRespMsg, respLen, &pAuthenticateResp); + if (CASA_SUCCESS(retStatus)) + { + // Return the auth token to the caller + pCacheEntry = CreateSessionTokenCacheEntry(pAuthContext->pContext, + retStatus, + pAuthenticateResp->pToken, + pAuthenticateResp->tokenLifetime, + pCredStoreScope); + + pAuthenticateResp->pToken = NULL; // To keep us from freeing the buffer + + // Free the Authenticate response object + RelAuthenticateResp(pAuthenticateResp); + } + } + else + { + DbgTrace(0, "-ObtainSessionToken- Authenticate Rpc failure, error = %08X\n", retStatus); + } + + // Free resources that may be hanging around + if (pRespMsg) + free(pRespMsg); + + free(pReqMsg); + } + else + { + DbgTrace(0, "-ObtainSessionToken- Error building Authenticate msg\n", 0); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + + // Add the entry to the cache if successful or if the reason that we failed + // was because the server was unavailable. + if (CasaStatusCode(retStatus) == CASA_STATUS_AUTH_SERVER_UNAVAILABLE) + { + pCacheEntry = CreateSessionTokenCacheEntry(pAuthContext->pContext, + retStatus, + NULL, + DEFAULT_RETRY_LIFETIME, + pCredStoreScope); + + } + + // Release the cache entry if the resulting status is not successful + if (!CASA_SUCCESS(retStatus)) + { + FreeAuthCacheEntry(pCacheEntry); + } + + // Free up the buffer associated with the authentication mechanism token + free(pAuthMechToken); + } + else + { + // Free the entry + FreeAuthCacheEntry(pCacheEntry); + } + + // Advance to the next entry + pListEntry = pListEntry->Flink; + } + + // Return session token if successful + if (CASA_SUCCESS(retStatus)) + { + // Allocate a buffer for the return token + *ppSessionToken = (char*) malloc(strlen(pCacheEntry->token) + 1); + if (*ppSessionToken) + { + // Copy the token onto the allocated buffer + strcpy(*ppSessionToken, pCacheEntry->token); + } + else + { + DbgTrace(0, "-ObtainSessionToken- Buffer allocation failure\n", 0); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + + FreeAuthCacheEntry(pCacheEntry); + } + + DbgTrace(1, "-ObtainSessionToken- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +static +CasaStatus +ObtainAuthTokenFromServer( + IN const char *pServiceName, + IN const char *pHostName, + INOUT char **ppAuthToken, + INOUT int *pTokenLifetime, + IN void *pCredStoreScope) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus = CASA_STATUS_SUCCESS; + RpcSession *pRpcSession; + + DbgTrace(1, "-ObtainAuthTokenFromServer- Start\n", 0); + + // Initialize output parameter + *ppAuthToken = NULL; + + // Open Rpc Session to the auth service at the specified host + pRpcSession = OpenRpcSession((g_pATSHostName != NULL) ? g_pATSHostName : pHostName, + g_ATSPort); + if (pRpcSession) + { + char *pReqMsg = NULL; + char *pRespMsg = NULL; + int respLen; + AuthPolicy *pAuthPolicy = NULL; + GetAuthPolicyResp *pGetAuthPolicyResp = NULL; + GetAuthTokenResp *pGetAuthTokenResp = NULL; + char *pSessionToken = NULL; + + // Request the auth parameters associated with this service + pReqMsg = BuildGetAuthPolicyMsg(pServiceName, "localhost"); // tbd - This will be changed in the future so that we can support services residing in a different host than the ATS + if (pReqMsg) + { + // Issue rpc + retStatus = Rpc(pRpcSession, + "GetAuthPolicy", + g_rpcFlags, + pReqMsg, + &pRespMsg, + &respLen); + if (CASA_SUCCESS(retStatus)) + { + // Create GetAuthPolicy response object + retStatus = CreateGetAuthPolicyResp(pRespMsg, respLen, &pGetAuthPolicyResp); + if (CASA_SUCCESS(retStatus)) + { + // Create the AuthPolicy object + retStatus = CreateAuthPolicy(pGetAuthPolicyResp->pPolicy, + pGetAuthPolicyResp->policyLen, + &pAuthPolicy); + if (CASA_SUCCESS(retStatus)) + { + // Now try to obtain a session token + retStatus = ObtainSessionToken(pRpcSession, + pAuthPolicy, + (g_pATSHostName != NULL) ? g_pATSHostName : pHostName, + pCredStoreScope, + &pSessionToken); + if (CASA_SUCCESS(retStatus)) + { + // Request auth token for the service + free(pReqMsg); + pReqMsg = BuildGetAuthTokenMsg(pServiceName, "localhost", pSessionToken); // tbd - This will be changed in the future so that we can support services residing in a different host than the ATS + if (pReqMsg) + { + // Free the previous response msg buffer + free(pRespMsg); + pRespMsg = NULL; + + // Issue rpc + retStatus = Rpc(pRpcSession, + "GetAuthToken", + g_rpcFlags, + pReqMsg, + &pRespMsg, + &respLen); + if (CASA_SUCCESS(retStatus)) + { + // Create GetAuthPolicy response object + retStatus = CreateGetAuthTokenResp(pRespMsg, respLen, &pGetAuthTokenResp); + if (CASA_SUCCESS(retStatus)) + { + // Return the auth token to the caller + *ppAuthToken = pGetAuthTokenResp->pToken; + pGetAuthTokenResp->pToken = NULL; // To keep us from freeing the buffer + *pTokenLifetime = pGetAuthTokenResp->tokenLifetime; + } + else + { + DbgTrace(0, "-ObtainAuthTokenFromServer- Failed to create GetAuthTokenResp object, error = %08X\n", retStatus); + } + } + else + { + DbgTrace(0, "-ObtainAuthTokenFromServer- GetAuthToken Rpc failure, error = %08X\n", retStatus); + } + } + else + { + DbgTrace(0, "-ObtainAuthTokenFromServer- Error building GetAuthToken msg\n", 0); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + } + else + { + DbgTrace(0, "-ObtainAuthTokenFromServer- Failed to obtain session token, error = %08X\n", retStatus); + } + } + else + { + DbgTrace(0, "-ObtainAuthTokenFromServer- Failed to create AuthPolicy object, error = %08X\n", retStatus); + } + } + else + { + DbgTrace(0, "-ObtainAuthTokenFromServer- Failed to create GetAuthPolicyResp object, error = %08X\n", retStatus); + } + } + else + { + DbgTrace(0, "-ObtainAuthTokenFromServer- GetAuthPolicy Rpc failure, error = %08X\n", retStatus); + } + + // Free resources that may be hanging around + if (pReqMsg) + free(pReqMsg); + + if (pRespMsg) + free(pRespMsg); + + if (pSessionToken) + free(pSessionToken); + + if (pGetAuthTokenResp) + RelGetAuthTokenResp(pGetAuthTokenResp); + + if (pGetAuthPolicyResp) + RelGetAuthPolicyResp(pGetAuthPolicyResp); + + if (pAuthPolicy) + RelAuthPolicy(pAuthPolicy); + } + else + { + DbgTrace(0, "-ObtainAuthTokenFromServer- Error building GetAuthPolicy msg\n", 0); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + + // Close the Rpc Session + CloseRpcSession(pRpcSession); + } + else + { + DbgTrace(0, "-ObtainAuthTokenFromServer- Error opening Rpc session\n", 0); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + + DbgTrace(1, "-ObtainAuthTokenFromServer- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +CasaStatus +ObtainAuthTokenInt( + IN const char *pServiceName, + IN const char *pHostName, + INOUT char *pAuthTokenBuf, + INOUT int *pAuthTokenBufLen, + IN void *pCredStoreScope) +// +// Arguments: +// pServiceName - +// Pointer to NULL terminated string that contains the +// name of the service to which the client is trying to +// authenticate. +// +// pHostName - +// Pointer to NULL terminated string that contains the +// name of the host where resides the service to which the +// client is trying to authenticate. Note that the name +// can either be a DNS name or a dotted IP address. +// +// pAuthTokenBuf - +// Pointer to buffer that will receive the authentication +// token. The length of this buffer is specified by the +// pAuthTokenBufLen parameter. Note that the the authentication +// token will be in the form of a NULL terminated string. +// +// pAuthTokenBufLen - +// Pointer to integer that contains the length of the +// buffer pointed at by pAuthTokenBuf. Upon return of the +// function, the integer will contain the actual length +// of the authentication token if the function successfully +// completes or the buffer length required if the function +// fails because the buffer pointed at by pAuthTokenBuf is +// not large enough. +// +// pCredStoreScope - +// Pointer to CASA structure for scoping credential store access +// to specific users. This can only be leveraged by applications +// running in the context of System. + +// Returns: +// Casa Status +// +// Description: +// Get authentication token to authenticate user to specified +// service at host. The user is scoped using the info associated +// with the magic cookie. +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus = CASA_STATUS_SUCCESS; + AuthCacheEntry *pCacheEntry; + char *pNormalizedHostName; + char *pToken; + HANDLE hUserMutex = NULL; + + DbgTrace(1, "-ObtainAuthTokenInt- Start\n", 0); + + // Verify the input parameters + if (pServiceName == NULL + || pHostName == NULL + || pAuthTokenBufLen == NULL + || (*pAuthTokenBufLen != 0 && pAuthTokenBuf == NULL)) + { + DbgTrace(0, "-ObtainAuthTokenInt- Invalid parameter\n", 0); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_INVALID_PARAMETER); + goto exit; + } + + DbgTrace(1, "-ObtainAuthTokenInt- ServiceName = %s\n", pServiceName); + DbgTrace(1, "-ObtainAuthTokenInt- HostName = %s\n", pHostName); + DbgTrace(1, "-ObtainAuthTokenInt- BufferLength = %d\n", *pAuthTokenBufLen); + + // Obtain our synchronization mutex + AcquireModuleMutex; + + // Create user synchronization mutex + retStatus = CreateUserMutex(&hUserMutex); + if (retStatus != CASA_STATUS_SUCCESS) + { + DbgTrace(0, "-ObtainAuthTokenInt- Error creating mutex for the user\n", 0); + goto exit; + } + + // Make sure we are fully initialized + if (g_bInitialized == false) + { + retStatus = InitializeLibrary(); + + if (retStatus == CASA_STATUS_SUCCESS) + { + g_bInitialized = true; + } + else + { + goto exit; + } + } + + // Release our synchronization mutex + ReleaseModuleMutex; + + // Normalize the host name + pNormalizedHostName = NormalizeHostName(pHostName); + if (pNormalizedHostName) + { + // Start user process synchronization + AcquireUserMutex(hUserMutex); + + // Try to find a cache entry for the service + pCacheEntry = FindAuthTokenEntryInCache(pServiceName, + pNormalizedHostName, + pCredStoreScope); + if (pCacheEntry == NULL) + { + // Initialize to retry in case of failure + int cacheEntryLifetime = DEFAULT_RETRY_LIFETIME; + + // Cache entry created, now try to obtain auth token from the CASA Server + retStatus = ObtainAuthTokenFromServer(pServiceName, + pNormalizedHostName, + &pToken, + &cacheEntryLifetime, + pCredStoreScope); + + // Add the entry to the cache if successful or if the reason that we failed + // was because the server was un-available. + if (CASA_SUCCESS(retStatus) + || CasaStatusCode(retStatus) == CASA_STATUS_AUTH_SERVER_UNAVAILABLE) + { + pCacheEntry = CreateAuthTokenCacheEntry(pServiceName, + pNormalizedHostName, + retStatus, + pToken, + cacheEntryLifetime, + pCredStoreScope); + if (pCacheEntry) + { + // Release the cache entry if the resulting status is not successful + if (!CASA_SUCCESS(retStatus)) + { + FreeAuthCacheEntry(pCacheEntry); + } + } + } + } + else + { + // Cache entry found, update the return status with the information saved in it + // and release it if its status is not successful. + if (!CASA_SUCCESS(retStatus = pCacheEntry->status)) + { + FreeAuthCacheEntry(pCacheEntry); + } + } + + // Try to return auth token if we have one to return + if (CASA_SUCCESS(retStatus)) + { + int tokenLen = (int) strlen(pCacheEntry->token) + 1; + + // We have an authentication token, try to return it to the caller + // after verifying that the supplied buffer is big enough. + if (*pAuthTokenBufLen >= tokenLen) + { + // Return the auth token to the caller + DbgTrace(2, "-ObtainAuthTokenInt- Copying the token into the callers buffer\n", 0); + strcpy(pAuthTokenBuf, pCacheEntry->token); + } + else + { + DbgTrace(0, "-ObtainAuthTokenInt- The supplied buffer is not large enough", 0); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_BUFFER_OVERFLOW); + } + + // Return the token length to the caller + *pAuthTokenBufLen = tokenLen; + + FreeAuthCacheEntry(pCacheEntry); + } + + // Stop user process synchronization + ReleaseUserMutex(hUserMutex); + + // Free the space allocated for the normalized host name + free(pNormalizedHostName); + } + else + { + DbgTrace(0, "-ObtainAuthTokenInt- Host name normalization failed\n", 0); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_UNSUCCESSFUL); + } + +exit: + + if (hUserMutex != NULL) + { + DestroyUserMutex(hUserMutex); + } + DbgTrace(1, "-ObtainAuthTokenInt- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +CasaStatus SSCS_CALL +ObtainAuthToken( + IN const char *pServiceName, + IN const char *pHostName, + INOUT char *pAuthTokenBuf, + INOUT int *pAuthTokenBufLen) +// +// Arguments: +// pServiceName - +// Pointer to NULL terminated string that contains the +// name of the service to which the client is trying to +// authenticate. +// +// pHostName - +// Pointer to NULL terminated string that contains the +// name of the host where resides the service to which the +// client is trying to authenticate. Note that the name +// can either be a DNS name or a dotted IP address. +// +// pAuthTokenBuf - +// Pointer to buffer that will receive the authentication +// token. The length of this buffer is specified by the +// pAuthTokenBufLen parameter. Note that the the authentication +// token will be in the form of a NULL terminated string. +// +// pAuthTokenBufLen - +// Pointer to integer that contains the length of the +// buffer pointed at by pAuthTokenBuf. Upon return of the +// function, the integer will contain the actual length +// of the authentication token if the function successfully +// completes or the buffer length required if the function +// fails because the buffer pointed at by pAuthTokenBuf is +// not large enough. +// +// Returns: +// Casa Status +// +// Description: +// Get authentication token to authenticate user to specified +// service at host. +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus; + + DbgTrace(1, "-ObtainAuthToken- Start\n", 0); + + // Call our internal worker + retStatus = ObtainAuthTokenInt(pServiceName, + pHostName, + pAuthTokenBuf, + pAuthTokenBufLen, + NULL); + + DbgTrace(1, "-ObtainAuthToken- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +int +InitializeLibrary(void) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + int retStatus = -1; + int getConfigStatus = -1; + ConfigIf *pClientConfigIf; + char *pATSPortSetting; + char *pDisableSecureConnections; + char *pAllowInvalidCerts; + char *pUsersCannotAllowInvalidCerts; + + DbgTrace(1, "-InitializeLibrary- Start\n", 0); + + // Try to obtain client configuration settings + getConfigStatus = GetConfigInterface(clientConfigFolder, + "client", + &pClientConfigIf); + if (CASA_SUCCESS(getConfigStatus) + && CasaStatusCode(getConfigStatus) != CASA_STATUS_OBJECT_NOT_FOUND) + { + // Check if an ATS hostname has been configured + g_pATSHostName = pClientConfigIf->getEntryValue(pClientConfigIf, "ATS-hostname"); + if (g_pATSHostName != NULL) + { + DbgTrace(0, "-InitializeLibrary- ATS hostname configured = %s\n", g_pATSHostName); + } + + // Check if the DisableSecureConnections setting has been configured + pDisableSecureConnections = pClientConfigIf->getEntryValue(pClientConfigIf, "DisableSecureConnections"); + if (pDisableSecureConnections != NULL) + { + DbgTrace(0, "-InitializeLibrary- DisableSecureConnections setting configured = %s\n", pDisableSecureConnections); + + // Adjust the g_rpcFlags variable based on the setting + if (stricmp(pDisableSecureConnections, "true") == 0) + { + g_rpcFlags &= ~SECURE_RPC_FLAG; + + // Change the default ATS port to 80 from 443 + g_ATSPort = 80; + } + else if (stricmp(pDisableSecureConnections, "false") == 0) + { + g_rpcFlags |= SECURE_RPC_FLAG; + } + + // Free the buffer holding the DisableSecureConnections setting + free(pDisableSecureConnections); + } + + // Check the AllowInvalidCerts setting if using secure connections + if (g_rpcFlags & SECURE_RPC_FLAG) + { + // Check if the AllowInvalidCerts setting has been configured + pAllowInvalidCerts = pClientConfigIf->getEntryValue(pClientConfigIf, "AllowInvalidCerts"); + if (pAllowInvalidCerts != NULL) + { + DbgTrace(0, "-InitializeLibrary- AllowInvalidCerts setting configured = %s\n", pAllowInvalidCerts); + + // Adjust the g_rpcFlags variable based on the setting + if (stricmp(pAllowInvalidCerts, "false") == 0) + { + g_rpcFlags &= ~ALLOW_INVALID_CERTS_RPC_FLAG; + } + else if (stricmp(pAllowInvalidCerts, "true") == 0) + { + g_rpcFlags |= ALLOW_INVALID_CERTS_RPC_FLAG; + } + + // Free the buffer holding the AllowInvalidCerts setting + free(pAllowInvalidCerts); + } + + // Check the UsersCannotAllowInvalidCerts setting if not allowing invalid certs. + if ((g_rpcFlags & ALLOW_INVALID_CERTS_RPC_FLAG) == 0) + { + // Check if the UsersCannotAllowInvalidCerts setting has been configured + pUsersCannotAllowInvalidCerts = pClientConfigIf->getEntryValue(pClientConfigIf, "UsersCannotAllowInvalidCerts"); + if (pUsersCannotAllowInvalidCerts != NULL) + { + DbgTrace(0, "-InitializeLibrary- UsersCannotAllowInvalidCerts setting configured = %s\n", pUsersCannotAllowInvalidCerts); + + // Adjust the g_rpcFlags variable based on the setting + if (stricmp(pUsersCannotAllowInvalidCerts, "false") == 0) + { + g_rpcFlags |= ALLOW_INVALID_CERTS_USER_APPROVAL_RPC_FLAG; + } + else if (stricmp(pUsersCannotAllowInvalidCerts, "true") == 0) + { + g_rpcFlags &= ~ALLOW_INVALID_CERTS_USER_APPROVAL_RPC_FLAG; + } + + // Free the buffer holding the UsersCannotAllowInvalidCerts setting + free(pUsersCannotAllowInvalidCerts); + } + } + } + + // Check if an ATS port number has been configured + pATSPortSetting = pClientConfigIf->getEntryValue(pClientConfigIf, "ATS-port"); + if (pATSPortSetting != NULL) + { + DbgTrace(0, "-InitializeLibrary- ATS port number configured = %s\n", pATSPortSetting); + + // Convert the number to hex + g_ATSPort = (int) dtoul(pATSPortSetting, strlen(pATSPortSetting)); + + // Free the buffer holding the port number + free(pATSPortSetting); + } + + // Release config interface instance + pClientConfigIf->releaseReference(pClientConfigIf); + } + + // Initialize the host name normalization + retStatus = InitializeHostNameNormalization(); + if (CASA_SUCCESS(retStatus)) + { + // Normalize ATS host name if configured + if (g_pATSHostName) + { + char *pNormalizedHostName = NormalizeHostName(g_pATSHostName); + if (pNormalizedHostName) + { + // Use this name instead of the one that we already have + free(g_pATSHostName); + g_pATSHostName = pNormalizedHostName; + } + else + { + DbgTrace(0, "-InitializeLibrary- ATS Hostname normalization failed\n", 0); + } + } + + // Initialize the auth cache + retStatus = InitializeAuthCache(); + if (CASA_SUCCESS(retStatus)) + { + retStatus = InitializeRpc(); + } + else + { + DbgTrace(0, "-InitializeLibrary- Auth cache intialization failed\n", 0); + } + } + else + { + DbgTrace(0, "-InitializeLibrary- HostName Normalizer intialization failed\n", 0); + } + + DbgTrace(1, "-InitializeLibrary- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +//++======================================================================= +//++======================================================================= + diff --git a/CASA-auth-token/client/core/getpolicymsg.c b/CASA-auth-token/client/core/getpolicymsg.c new file mode 100644 index 00000000..ccb24738 --- /dev/null +++ b/CASA-auth-token/client/core/getpolicymsg.c @@ -0,0 +1,745 @@ +/*********************************************************************** + * + * 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 + * + ***********************************************************************/ + + +//===[ Include files ]===================================================== + +#include "internal.h" + +//===[ Type definitions ]================================================== + +// +// Parse states +// +#define AWAITING_ROOT_ELEMENT_START 0x0 +#define AWAITING_ROOT_ELEMENT_END 0x1 +#define AWAITING_STATUS_ELEMENT_START 0x2 +#define AWAITING_STATUS_ELEMENT_END 0x3 +#define AWAITING_STATUS_DATA 0x4 +#define AWAITING_DESCRIPTION_ELEMENT_START 0x5 +#define AWAITING_DESCRIPTION_ELEMENT_END 0x6 +#define AWAITING_DESCRIPTION_DATA 0x7 +#define AWAITING_AUTH_TOKEN_ELEMENT_START 0x8 +#define AWAITING_AUTH_TOKEN_ELEMENT_END 0x9 +#define AWAITING_AUTH_TOKEN_DATA 0xA +#define AWAITING_AUTH_POLICY_ELEMENT_START 0xB +#define AWAITING_AUTH_POLICY_ELEMENT_END 0xC +#define AWAITING_AUTH_POLICY_DATA 0xD +#define DONE_PARSING 0xE + +// +// Get Authentication Policy Response Parse Structure +// +typedef struct _GetAuthPolicyRespParse +{ + XML_Parser p; + int state; + int elementDataProcessed; + GetAuthPolicyResp *pGetAuthPolicyResp; + CasaStatus status; + +} GetAuthPolicyRespParse, *PGetAuthPolicyRespParse; + + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + + +//++======================================================================= +char* +BuildGetAuthPolicyMsg( + IN const char *pServiceName, + IN const char *pHostName) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + char *pMsg = NULL; + int bufferSize; + + DbgTrace(1, "-BuildGetAuthPolicyMsg- Start\n", 0); + + /* + * The format of the get authentication policy request message is as follows: + * + * + * + * service name<\service> + * host name + * + * + */ + + // Determine the buffer size necessary to hold the msg + bufferSize = strlen(XML_DECLARATION) + + 2 // crlf + + 1 // < + + strlen(GET_AUTH_POLICY_REQUEST_ELEMENT_NAME) + + 3 // >crlf + + 1 // < + + strlen(SERVICE_ELEMENT_NAME) + + 1 // > + + strlen(pServiceName) + + 2 // crlf + + 2 // + + strlen(pHostName) + + 2 // crlf + + 2 // null + + // Allocate the msg buffer + pMsg = (char*) malloc(bufferSize); + if (pMsg) + { + // Now build the message + memset(pMsg, 0, bufferSize); + strcat(pMsg, XML_DECLARATION); + strcat(pMsg, "\r\n"); + strcat(pMsg, "<"); + strcat(pMsg, GET_AUTH_POLICY_REQUEST_ELEMENT_NAME); + strcat(pMsg, ">\r\n"); + strcat(pMsg, "<"); + strcat(pMsg, SERVICE_ELEMENT_NAME); + strcat(pMsg, ">"); + strcat(pMsg, pServiceName); + strcat(pMsg, "\r\n"); + strcat(pMsg, "<"); + strcat(pMsg, HOST_ELEMENT_NAME); + strcat(pMsg, ">"); + strcat(pMsg, pHostName); + strcat(pMsg, "\r\n"); + strcat(pMsg, ""); + } + else + { + DbgTrace(0, "-BuildGetAuthPolicyMsg- Buffer allocation error\n", 0); + } + + DbgTrace(1, "-BuildGetAuthPolicyMsg- End, pMsg = %0lX\n", (long) pMsg); + + return pMsg; +} + + +//++======================================================================= +static +void XMLCALL +GetAuthPolicyRespStartElementHandler( + IN GetAuthPolicyRespParse *pGetAuthPolicyRespParse, + IN const XML_Char *name, + IN const XML_Char **atts) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + DbgTrace(2, "-GetAuthPolicyRespStartElementHandler- Start\n", 0); + + // Proceed based on the state + switch (pGetAuthPolicyRespParse->state) + { + case AWAITING_ROOT_ELEMENT_START: + + // In this state, we are only expecting the Get Authentication + // Policy Response Element. + if (strcmp(name, GET_AUTH_POLICY_RESPONSE_ELEMENT_NAME) == 0) + { + // Good, advance to the next state. + pGetAuthPolicyRespParse->state = AWAITING_STATUS_ELEMENT_START; + } + else + { + DbgTrace(0, "-GetAuthPolicyRespStartElementHandler- Un-expected start element\n", 0); + XML_StopParser(pGetAuthPolicyRespParse->p, XML_FALSE); + } + break; + + case AWAITING_STATUS_ELEMENT_START: + + // In this state, we are only expecting the Status Element. + if (strcmp(name, STATUS_ELEMENT_NAME) == 0) + { + // Good, advance to the next state. + pGetAuthPolicyRespParse->state = AWAITING_DESCRIPTION_ELEMENT_START; + } + else + { + DbgTrace(0, "-GetAuthPolicyRespStartElementHandler- Un-expected start element\n", 0); + XML_StopParser(pGetAuthPolicyRespParse->p, XML_FALSE); + } + break; + + case AWAITING_DESCRIPTION_ELEMENT_START: + + // In this state, we are only expecting the Description Element. + if (strcmp(name, DESCRIPTION_ELEMENT_NAME) == 0) + { + // Good, advance to the next state. + pGetAuthPolicyRespParse->state = AWAITING_DESCRIPTION_DATA; + } + else + { + DbgTrace(0, "-GetAuthPolicyRespStartElementHandler- Un-expected start element\n", 0); + XML_StopParser(pGetAuthPolicyRespParse->p, XML_FALSE); + } + break; + + case AWAITING_AUTH_POLICY_ELEMENT_START: + + // In this state, we are only expecting the Authentication Policy Element. + if (strcmp(name, AUTH_POLICY_ELEMENT_NAME) == 0) + { + // Good, advance to the next state. + pGetAuthPolicyRespParse->state = AWAITING_AUTH_POLICY_DATA; + } + else + { + DbgTrace(0, "-GetAuthPolicyRespStartElementHandler- Un-expected start element\n", 0); + XML_StopParser(pGetAuthPolicyRespParse->p, XML_FALSE); + } + break; + + default: + DbgTrace(0, "-GetAuthPolicyRespStartElementHandler- Un-expected state = %d\n", pGetAuthPolicyRespParse->state); + XML_StopParser(pGetAuthPolicyRespParse->p, XML_FALSE); + break; + } + + DbgTrace(2, "-GetAuthPolicyRespStartElementHandler- End\n", 0); +} + + +//++======================================================================= +static +CasaStatus +ConsumeElementData( + IN GetAuthPolicyRespParse *pGetAuthPolicyRespParse, + IN const XML_Char *s, + IN int len, + INOUT char **ppElementData, + INOUT int *pElementDataLen) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus = CASA_STATUS_SUCCESS; + + DbgTrace(3, "-ConsumeElementData- Start\n", 0); + + // Proceed based on whether or not we have already consumed data + // for this element. + if (*ppElementData == NULL) + { + // We have not yet consumed data for this element + pGetAuthPolicyRespParse->elementDataProcessed = len; + + // Allocate a buffer to hold this element data (null terminated). + *ppElementData = (char*) malloc(len + 1); + if (*ppElementData) + { + memset(*ppElementData, 0, len + 1); + memcpy(*ppElementData, s, len); + + // Return the length of the element data buffer + *pElementDataLen = pGetAuthPolicyRespParse->elementDataProcessed + 1; + } + else + { + DbgTrace(0, "-ConsumeElementData- Buffer allocation failure\n", 0); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + } + else + { + char *pNewBuf; + + // We have already received token data, append this data to it. + pNewBuf = (char*) malloc(pGetAuthPolicyRespParse->elementDataProcessed + len + 1); + if (pNewBuf) + { + memset(pNewBuf, + 0, + pGetAuthPolicyRespParse->elementDataProcessed + len + 1); + memcpy(pNewBuf, + *ppElementData, + pGetAuthPolicyRespParse->elementDataProcessed); + memcpy(pNewBuf + pGetAuthPolicyRespParse->elementDataProcessed, s, len); + pGetAuthPolicyRespParse->elementDataProcessed += len; + + // Swap the buffers + free(*ppElementData); + *ppElementData = pNewBuf; + + // Return the length of the element data buffer + *pElementDataLen = pGetAuthPolicyRespParse->elementDataProcessed + 1; + } + else + { + DbgTrace(0, "-ConsumeElementData- Buffer allocation failure\n", 0); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + } + + DbgTrace(3, "-ConsumeElementData- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +static +void XMLCALL +GetAuthPolicyRespCharDataHandler( + IN GetAuthPolicyRespParse *pGetAuthPolicyRespParse, + IN const XML_Char *s, + IN int len) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + DbgTrace(2, "-GetAuthPolicyRespCharDataHandler- Start\n", 0); + + // Just exit if being called to process white space + if (*s == '\n' || *s == '\r' || *s == '\t' || *s == ' ') + { + goto exit; + } + + // Proceed based on the state + switch (pGetAuthPolicyRespParse->state) + { + case AWAITING_DESCRIPTION_DATA: + case AWAITING_DESCRIPTION_ELEMENT_END: + + // Ignore the status description data for now. + // tbd + + // Advanced to the next state + pGetAuthPolicyRespParse->state = AWAITING_DESCRIPTION_ELEMENT_END; + break; + + case AWAITING_STATUS_DATA: + + // Set the appropriate status in the AuthenticationResp based on the + // returned status. + if (strncmp(HTTP_OK_STATUS_CODE, s, len) == 0) + { + pGetAuthPolicyRespParse->status = CASA_STATUS_SUCCESS; + } + else if (strncmp(HTTP_UNAUTHORIZED_STATUS_CODE, s, len) == 0) + { + pGetAuthPolicyRespParse->status = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_AUTHENTICATION_FAILURE); + } + else if (strncmp(HTTP_NOT_FOUND_STATUS_CODE, s, len) == 0) + { + pGetAuthPolicyRespParse->status = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_NOT_CONFIGURED); + } + else if (strncmp(HTTP_SERVER_ERROR_STATUS_CODE, s, len) == 0) + { + pGetAuthPolicyRespParse->status = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_SERVER_ERROR); + } + else + { + DbgTrace(0, "-GetAuthPolicyRespCharDataHandler- Un-expected status\n", 0); + pGetAuthPolicyRespParse->status = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_UNSUCCESSFUL); + } + + // Advanced to the next state + pGetAuthPolicyRespParse->state = AWAITING_STATUS_ELEMENT_END; + break; + + case AWAITING_AUTH_POLICY_DATA: + case AWAITING_AUTH_POLICY_ELEMENT_END: + + pGetAuthPolicyRespParse->status = ConsumeElementData(pGetAuthPolicyRespParse, + s, + len, + &pGetAuthPolicyRespParse->pGetAuthPolicyResp->pPolicy, + &pGetAuthPolicyRespParse->pGetAuthPolicyResp->policyLen); + if (CASA_SUCCESS(pGetAuthPolicyRespParse->status)) + { + // Advanced to the next state + pGetAuthPolicyRespParse->state = AWAITING_AUTH_POLICY_ELEMENT_END; + } + else + { + XML_StopParser(pGetAuthPolicyRespParse->p, XML_FALSE); + } + break; + + default: + DbgTrace(0, "-GetAuthPolicyRespCharDataHandler- Un-expected state = %d\n", pGetAuthPolicyRespParse->state); + XML_StopParser(pGetAuthPolicyRespParse->p, XML_FALSE); + break; + } + +exit: + + DbgTrace(2, "-GetAuthPolicyRespCharDataHandler- End\n", 0); +} + + +//++======================================================================= +static +void XMLCALL +GetAuthPolicyRespEndElementHandler( + IN GetAuthPolicyRespParse *pGetAuthPolicyRespParse, + IN const XML_Char *name) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + DbgTrace(2, "-GetAuthPolicyRespEndElementHandler- Start\n", 0); + + // Proceed based on the state + switch (pGetAuthPolicyRespParse->state) + { + case AWAITING_ROOT_ELEMENT_END: + + // In this state, we are only expecting the Get Authentication + // Policy Response Element. + if (strcmp(name, GET_AUTH_POLICY_RESPONSE_ELEMENT_NAME) == 0) + { + // Done. + pGetAuthPolicyRespParse->state = DONE_PARSING; + } + else + { + DbgTrace(0, "-GetAuthPolicyRespEndHandler- Un-expected end element\n", 0); + XML_StopParser(pGetAuthPolicyRespParse->p, XML_FALSE); + } + break; + + case AWAITING_DESCRIPTION_ELEMENT_END: + + // In this state, we are only expecting the Description Element. + if (strcmp(name, DESCRIPTION_ELEMENT_NAME) == 0) + { + // Good, advance to the next state. + pGetAuthPolicyRespParse->state = AWAITING_STATUS_DATA; + } + else + { + DbgTrace(0, "-GetAuthPolicyRespEndElementHandler- Un-expected end element\n", 0); + XML_StopParser(pGetAuthPolicyRespParse->p, XML_FALSE); + } + break; + + case AWAITING_STATUS_ELEMENT_END: + + // In this state, we are only expecting the Status Element. + if (strcmp(name, STATUS_ELEMENT_NAME) == 0) + { + // Good, advance to the next state based on the status code. + if (CASA_SUCCESS(pGetAuthPolicyRespParse->status)) + { + // The request completed successfully + pGetAuthPolicyRespParse->state = AWAITING_AUTH_POLICY_ELEMENT_START; + } + else + { + pGetAuthPolicyRespParse->state = AWAITING_ROOT_ELEMENT_END; + } + } + else + { + DbgTrace(0, "-GetAuthPolicyRespEndElementHandler- Un-expected start element\n", 0); + XML_StopParser(pGetAuthPolicyRespParse->p, XML_FALSE); + } + break; + + case AWAITING_AUTH_POLICY_ELEMENT_END: + + // In this state, we are only expecting the Authentication Policy Element. + if (strcmp(name, AUTH_POLICY_ELEMENT_NAME) == 0) + { + // Good, advance to the next state. + pGetAuthPolicyRespParse->state = AWAITING_ROOT_ELEMENT_END; + } + else + { + DbgTrace(0, "-GetAuthPolicyRespEndElementHandler- Un-expected start element\n", 0); + XML_StopParser(pGetAuthPolicyRespParse->p, XML_FALSE); + } + break; + + default: + DbgTrace(0, "-GetAuthPolicyRespEndElementHandler- Un-expected state = %d\n", pGetAuthPolicyRespParse->state); + XML_StopParser(pGetAuthPolicyRespParse->p, XML_FALSE); + break; + } + + DbgTrace(2, "-GetAuthPolicyRespEndElementHandler- End\n", 0); +} + + +//++======================================================================= +CasaStatus +CreateGetAuthPolicyResp( + IN char *pRespMsg, + IN int respLen, + INOUT GetAuthPolicyResp **ppGetAuthPolicyResp) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus = CASA_STATUS_SUCCESS; + GetAuthPolicyRespParse getAuthPolicyRespParse = {0}; + GetAuthPolicyResp *pGetAuthPolicyResp; + + DbgTrace(1, "-CreateGetAuthPolicyResp- Start\n", 0); + + /* + * When a get authentication policy request is processed successfully, the + * server replies to the client with a message with the following format: + * + * + * + * ok200 + * authentication policy data + * + * + * When a get authentication policy request fails to be successfully processed, + * the server responds with an error and an error description string. The message + * format of an unsuccessful reply is as follows: + * + * + * + * status descriptionstatus code + * + * + * Plase note that the protocol utilizes the status codes defined + * in the HTTP 1.1 Specification. + * + */ + + // Allocate GetAuthPolicyResp object + pGetAuthPolicyResp = malloc(sizeof(*pGetAuthPolicyResp)); + if (pGetAuthPolicyResp) + { + XML_Parser p; + + // Initialize the GetAuthPolicyResp object and set it in the + // parse oject. + memset(pGetAuthPolicyResp, 0, sizeof(*pGetAuthPolicyResp)); + getAuthPolicyRespParse.pGetAuthPolicyResp = pGetAuthPolicyResp; + + // Create parser + p = XML_ParserCreate(NULL); + if (p) + { + // Keep track of the parser in our parse object + getAuthPolicyRespParse.p = p; + + // Initialize the status within the parse object + getAuthPolicyRespParse.status = CASA_STATUS_SUCCESS; + + // Set the start and end element handlers + XML_SetElementHandler(p, + (XML_StartElementHandler) GetAuthPolicyRespStartElementHandler, + (XML_EndElementHandler) GetAuthPolicyRespEndElementHandler); + + // Set the character data handler + XML_SetCharacterDataHandler(p, (XML_CharacterDataHandler) GetAuthPolicyRespCharDataHandler); + + + // Set our user data + XML_SetUserData(p, &getAuthPolicyRespParse); + + // Parse the document + if (XML_Parse(p, pRespMsg, respLen, 1) == XML_STATUS_OK) + { + // Verify that the parse operation completed successfully + if (getAuthPolicyRespParse.state == DONE_PARSING) + { + // The parse operation succeded, obtain the status returned + // by the server. + retStatus = getAuthPolicyRespParse.status; + } + else + { + DbgTrace(0, "-CreateGetAuthPolicyResp- Parse operation did not complete\n", 0); + + // Check if a status has been recorded + if (getAuthPolicyRespParse.status != CASA_STATUS_SUCCESS) + { + retStatus = getAuthPolicyRespParse.status; + } + else + { + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_PROTOCOL_ERROR); + } + } + } + else + { + DbgTrace(0, "-CreateGetAuthPolicyResp- Parse error %d\n", XML_GetErrorCode(p)); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_PROTOCOL_ERROR); + } + + // Free the parser + XML_ParserFree(p); + } + else + { + DbgTrace(0, "-CreateGetAuthPolicyResp- Parser creation error\n", 0); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + + // Return the AuthenticationResp object to the caller if necessary + if (CASA_SUCCESS(retStatus)) + { + *ppGetAuthPolicyResp = pGetAuthPolicyResp; + } + else + { + free(pGetAuthPolicyResp); + } + } + else + { + DbgTrace(0, "-CreateGetAuthPolicyResp- Memory allocation error\n", 0); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + + DbgTrace(1, "-CreateGetAuthPolicyResp- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +void +RelGetAuthPolicyResp( + IN GetAuthPolicyResp *pGetAuthPolicyResp) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + DbgTrace(1, "-RelGetAuthPolicyResp- Start\n", 0); + + // Free the buffer holding the authentication policy + if (pGetAuthPolicyResp->pPolicy) + free(pGetAuthPolicyResp->pPolicy); + + // Free the GetAuthPolicyResp + free(pGetAuthPolicyResp); + + DbgTrace(1, "-RelGetAuthPolicyResp- End\n", 0); +} + + +//++======================================================================= +//++======================================================================= +//++======================================================================= + diff --git a/CASA-auth-token/client/core/gettokenmsg.c b/CASA-auth-token/client/core/gettokenmsg.c new file mode 100644 index 00000000..8a512f2b --- /dev/null +++ b/CASA-auth-token/client/core/gettokenmsg.c @@ -0,0 +1,793 @@ +/*********************************************************************** + * + * 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 + * + ***********************************************************************/ + + +//===[ Include files ]===================================================== + +#include "internal.h" + +//===[ Type definitions ]================================================== + +// +// Parse states +// +#define AWAITING_ROOT_ELEMENT_START 0x0 +#define AWAITING_ROOT_ELEMENT_END 0x1 +#define AWAITING_STATUS_ELEMENT_START 0x2 +#define AWAITING_STATUS_ELEMENT_END 0x3 +#define AWAITING_STATUS_DATA 0x4 +#define AWAITING_DESCRIPTION_ELEMENT_START 0x5 +#define AWAITING_DESCRIPTION_ELEMENT_END 0x6 +#define AWAITING_DESCRIPTION_DATA 0x7 +#define AWAITING_LIFETIME_DATA 0x8 +#define AWAITING_LIFETIME_ELEMENT_START 0x9 +#define AWAITING_LIFETIME_ELEMENT_END 0xA +#define AWAITING_AUTH_TOKEN_ELEMENT_START 0xB +#define AWAITING_AUTH_TOKEN_ELEMENT_END 0xC +#define AWAITING_AUTH_TOKEN_DATA 0xD +#define DONE_PARSING 0xE + +// +// Get Authentication Token Response Parse Structure +// +typedef struct _GetAuthTokenRespParse +{ + XML_Parser p; + int state; + int elementDataProcessed; + GetAuthTokenResp *pGetAuthTokenResp; + CasaStatus status; + +} GetAuthTokenRespParse, *PGetAuthTokenRespParse; + + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + +//++======================================================================= +char* +BuildGetAuthTokenMsg( + IN const char *pServiceName, + IN const char *pHostName, + IN char *pSessionToken) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + char *pMsg = NULL; + int bufferSize; + + DbgTrace(1, "-BuildGetAuthTokenMsg- Start\n", 0); + + /* + * The format of the get authentication token request message + * is as follows: + * + * + * + * service name + * host name + * session token data + * + * + */ + + // Determine the buffer size necessary to hold the msg + bufferSize = strlen(XML_DECLARATION) + + 2 // crlf + + 1 // < + + strlen(GET_AUTH_TOKEN_REQUEST_ELEMENT_NAME) + + 3 // >crlf + + 1 // < + + strlen(SERVICE_ELEMENT_NAME) + + 1 // > + + strlen(pServiceName) + + 2 // crlf + + 1 // < + + strlen(HOST_ELEMENT_NAME) + + 1 // > + + strlen(pHostName) + + 2 // crlf + + 1 // < + + strlen(SESSION_TOKEN_ELEMENT_NAME) + + 1 // > + + strlen(pSessionToken) + + 2 // crlf + + 2 // null + + // Allocate the msg buffer + pMsg = (char*) malloc(bufferSize); + if (pMsg) + { + // Now build the message + memset(pMsg, 0, bufferSize); + strcat(pMsg, XML_DECLARATION); + strcat(pMsg, "\r\n"); + strcat(pMsg, "<"); + strcat(pMsg, GET_AUTH_TOKEN_REQUEST_ELEMENT_NAME); + strcat(pMsg, ">\r\n"); + strcat(pMsg, "<"); + strcat(pMsg, SERVICE_ELEMENT_NAME); + strcat(pMsg, ">"); + strcat(pMsg, pServiceName); + strcat(pMsg, "\r\n"); + strcat(pMsg, "<"); + strcat(pMsg, HOST_ELEMENT_NAME); + strcat(pMsg, ">"); + strcat(pMsg, pHostName); + strcat(pMsg, "\r\n"); + strcat(pMsg, "<"); + strcat(pMsg, SESSION_TOKEN_ELEMENT_NAME); + strcat(pMsg, ">"); + strcat(pMsg, pSessionToken); + strcat(pMsg, "\r\n"); + strcat(pMsg, ""); + } + else + { + DbgTrace(0, "-BuildGetAuthTokenMsg- Buffer allocation error\n", 0); + } + + DbgTrace(1, "-BuildGetAuthTokenMsg- End, pMsg = %0lX\n", (long) pMsg); + + return pMsg; +} + + +//++======================================================================= +static +void XMLCALL +GetAuthTokenRespStartElementHandler( + IN GetAuthTokenRespParse *pGetAuthTokenRespParse, + IN const XML_Char *name, + IN const XML_Char **atts) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + DbgTrace(2, "-GetAuthTokenRespStartElementHandler- Start\n", 0); + + // Proceed based on the state + switch (pGetAuthTokenRespParse->state) + { + case AWAITING_ROOT_ELEMENT_START: + + // In this state, we are only expecting the Get Authentication + // Token Response Element. + if (strcmp(name, GET_AUTH_TOKEN_RESPONSE_ELEMENT_NAME) == 0) + { + // Good, advance to the next state. + pGetAuthTokenRespParse->state = AWAITING_STATUS_ELEMENT_START; + } + else + { + DbgTrace(0, "-GetAuthTokenRespStartElementHandler- Un-expected start element\n", 0); + XML_StopParser(pGetAuthTokenRespParse->p, XML_FALSE); + } + break; + + case AWAITING_STATUS_ELEMENT_START: + + // In this state, we are only expecting the Status Element. + if (strcmp(name, STATUS_ELEMENT_NAME) == 0) + { + // Good, advance to the next state. + pGetAuthTokenRespParse->state = AWAITING_DESCRIPTION_ELEMENT_START; + } + else + { + DbgTrace(0, "-GetAuthTokenRespStartElementHandler- Un-expected start element\n", 0); + XML_StopParser(pGetAuthTokenRespParse->p, XML_FALSE); + } + break; + + case AWAITING_DESCRIPTION_ELEMENT_START: + + // In this state, we are only expecting the Description Element. + if (strcmp(name, DESCRIPTION_ELEMENT_NAME) == 0) + { + // Good, advance to the next state. + pGetAuthTokenRespParse->state = AWAITING_DESCRIPTION_DATA; + } + else + { + DbgTrace(0, "-GetAuthTokenRespStartElementHandler- Un-expected start element\n", 0); + XML_StopParser(pGetAuthTokenRespParse->p, XML_FALSE); + } + break; + + case AWAITING_AUTH_TOKEN_ELEMENT_START: + + // In this state, we are only expecting the Authentication Token Element. + if (strcmp(name, AUTH_TOKEN_ELEMENT_NAME) == 0) + { + // Good, advance to the next state. + pGetAuthTokenRespParse->state = AWAITING_LIFETIME_ELEMENT_START; + } + else + { + DbgTrace(0, "-GetAuthTokenRespStartElementHandler- Un-expected start element\n", 0); + XML_StopParser(pGetAuthTokenRespParse->p, XML_FALSE); + } + break; + + case AWAITING_LIFETIME_ELEMENT_START: + + // In this state, we are only expecting the Lifetime Element. + if (strcmp(name, LIFETIME_ELEMENT_NAME) == 0) + { + // Good, advance to the next state. + pGetAuthTokenRespParse->state = AWAITING_LIFETIME_DATA; + } + else + { + DbgTrace(0, "-GetAuthTokenRespStartElementHandler- Un-expected start element\n", 0); + XML_StopParser(pGetAuthTokenRespParse->p, XML_FALSE); + } + break; + + default: + DbgTrace(0, "-GetAuthTokenRespStartElementHandler- Un-expected state = %d\n", pGetAuthTokenRespParse->state); + XML_StopParser(pGetAuthTokenRespParse->p, XML_FALSE); + break; + } + + DbgTrace(2, "-GetAuthTokenRespStartElementHandler- End\n", 0); +} + + +//++======================================================================= +static +CasaStatus +ConsumeElementData( + IN GetAuthTokenRespParse *pGetAuthTokenRespParse, + IN const XML_Char *s, + IN int len, + INOUT char **ppElementData, + INOUT int *pElementDataLen) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus = CASA_STATUS_SUCCESS; + + DbgTrace(3, "-ConsumeElementData- Start\n", 0); + + // Proceed based on whether or not we have already consumed data + // for this element. + if (*ppElementData == NULL) + { + // We have not yet consumed data for this element + pGetAuthTokenRespParse->elementDataProcessed = len; + + // Allocate a buffer to hold this element data (null terminated). + *ppElementData = (char*) malloc(len + 1); + if (*ppElementData) + { + memset(*ppElementData, 0, len + 1); + memcpy(*ppElementData, s, len); + + // Return the length of the element data buffer + *pElementDataLen = pGetAuthTokenRespParse->elementDataProcessed + 1; + } + else + { + DbgTrace(0, "-ConsumeElementData- Buffer allocation failure\n", 0); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + } + else + { + char *pNewBuf; + + // We have already received token data, append this data to it. + pNewBuf = (char*) malloc(pGetAuthTokenRespParse->elementDataProcessed + len + 1); + if (pNewBuf) + { + memset(pNewBuf, + 0, + pGetAuthTokenRespParse->elementDataProcessed + len + 1); + memcpy(pNewBuf, + *ppElementData, + pGetAuthTokenRespParse->elementDataProcessed); + memcpy(pNewBuf + pGetAuthTokenRespParse->elementDataProcessed, s, len); + pGetAuthTokenRespParse->elementDataProcessed += len; + + // Swap the buffers + free(*ppElementData); + *ppElementData = pNewBuf; + + // Return the length of the element data buffer + *pElementDataLen = pGetAuthTokenRespParse->elementDataProcessed + 1; + } + else + { + DbgTrace(0, "-ConsumeElementData- Buffer allocation failure\n", 0); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + } + + DbgTrace(3, "-ConsumeElementData- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +static +void XMLCALL +GetAuthTokenRespCharDataHandler( + IN GetAuthTokenRespParse *pGetAuthTokenRespParse, + IN const XML_Char *s, + IN int len) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + DbgTrace(2, "-GetAuthTokenRespCharDataHandler- Start\n", 0); + + // Just exit if being called to process white space + if (*s == '\n' || *s == '\r' || *s == '\t' || *s == ' ') + { + goto exit; + } + + // Proceed based on the state + switch (pGetAuthTokenRespParse->state) + { + case AWAITING_DESCRIPTION_DATA: + case AWAITING_DESCRIPTION_ELEMENT_END: + + // Ignore the status description data for now. + // tbd + + // Advanced to the next state + pGetAuthTokenRespParse->state = AWAITING_DESCRIPTION_ELEMENT_END; + break; + + case AWAITING_STATUS_DATA: + + // Set the appropriate status in the AuthenticationResp based on the + // returned status. + if (strncmp(HTTP_OK_STATUS_CODE, s, len) == 0) + { + pGetAuthTokenRespParse->status = CASA_STATUS_SUCCESS; + } + else if (strncmp(HTTP_UNAUTHORIZED_STATUS_CODE, s, len) == 0) + { + pGetAuthTokenRespParse->status = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_AUTHENTICATION_FAILURE); + } + else if (strncmp(HTTP_SERVER_ERROR_STATUS_CODE, s, len) == 0) + { + pGetAuthTokenRespParse->status = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_SERVER_ERROR); + } + else + { + DbgTrace(0, "-GetAuthTokenRespCharDataHandler- Un-expected status\n", 0); + pGetAuthTokenRespParse->status = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_UNSUCCESSFUL); + } + + // Advanced to the next state + pGetAuthTokenRespParse->state = AWAITING_STATUS_ELEMENT_END; + break; + + case AWAITING_LIFETIME_DATA: + + // Convert the lifetime string to a numeric value + pGetAuthTokenRespParse->pGetAuthTokenResp->tokenLifetime = dtoul(s, len); + + // Advanced to the next state + pGetAuthTokenRespParse->state = AWAITING_LIFETIME_ELEMENT_END; + break; + + case AWAITING_AUTH_TOKEN_DATA: + case AWAITING_AUTH_TOKEN_ELEMENT_END: + + // Consume the data + pGetAuthTokenRespParse->status = ConsumeElementData(pGetAuthTokenRespParse, + s, + len, + &pGetAuthTokenRespParse->pGetAuthTokenResp->pToken, + &pGetAuthTokenRespParse->pGetAuthTokenResp->tokenLen); + if (CASA_SUCCESS(pGetAuthTokenRespParse->status)) + { + // Advanced to the next state + pGetAuthTokenRespParse->state = AWAITING_AUTH_TOKEN_ELEMENT_END; + } + else + { + XML_StopParser(pGetAuthTokenRespParse->p, XML_FALSE); + } + break; + + default: + DbgTrace(0, "-GetAuthTokenRespCharDataHandler- Un-expected state = %d\n", pGetAuthTokenRespParse->state); + XML_StopParser(pGetAuthTokenRespParse->p, XML_FALSE); + break; + } + +exit: + + DbgTrace(2, "-GetAuthTokenRespCharDataHandler- End\n", 0); +} + + +//++======================================================================= +static +void XMLCALL +GetAuthTokenRespEndElementHandler( + IN GetAuthTokenRespParse *pGetAuthTokenRespParse, + IN const XML_Char *name) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + DbgTrace(2, "-GetAuthTokenRespEndElementHandler- Start\n", 0); + + // Proceed based on the state + switch (pGetAuthTokenRespParse->state) + { + case AWAITING_ROOT_ELEMENT_END: + + // In this state, we are only expecting the Get Authentication + // Token Response Element. + if (strcmp(name, GET_AUTH_TOKEN_RESPONSE_ELEMENT_NAME) == 0) + { + // Done. + pGetAuthTokenRespParse->state = DONE_PARSING; + } + else + { + DbgTrace(0, "-GetAuthTokenRespEndHandler- Un-expected end element\n", 0); + XML_StopParser(pGetAuthTokenRespParse->p, XML_FALSE); + } + break; + + case AWAITING_DESCRIPTION_ELEMENT_END: + + // In this state, we are only expecting the Description Element. + if (strcmp(name, DESCRIPTION_ELEMENT_NAME) == 0) + { + // Good, advance to the next state. + pGetAuthTokenRespParse->state = AWAITING_STATUS_DATA; + } + else + { + DbgTrace(0, "-GetAuthTokenRespEndElementHandler- Un-expected end element\n", 0); + XML_StopParser(pGetAuthTokenRespParse->p, XML_FALSE); + } + break; + + case AWAITING_STATUS_ELEMENT_END: + + // In this state, we are only expecting the Status Element. + if (strcmp(name, STATUS_ELEMENT_NAME) == 0) + { + // Good, advance to the next state based on the status code. + if (CASA_SUCCESS(pGetAuthTokenRespParse->status)) + { + // The request completed successfully + pGetAuthTokenRespParse->state = AWAITING_AUTH_TOKEN_ELEMENT_START; + } + else + { + pGetAuthTokenRespParse->state = AWAITING_ROOT_ELEMENT_END; + } + } + else + { + DbgTrace(0, "-GetAuthTokenRespEndElementHandler- Un-expected start element\n", 0); + XML_StopParser(pGetAuthTokenRespParse->p, XML_FALSE); + } + break; + + case AWAITING_LIFETIME_ELEMENT_END: + + // In this state, we are only expecting the Lifetime Element. + if (strcmp(name, LIFETIME_ELEMENT_NAME) == 0) + { + // Good, advance to the next state. + pGetAuthTokenRespParse->state = AWAITING_AUTH_TOKEN_DATA; + } + else + { + DbgTrace(0, "-GetAuthTokenRespEndElementHandler- Un-expected start element\n", 0); + XML_StopParser(pGetAuthTokenRespParse->p, XML_FALSE); + } + break; + + case AWAITING_AUTH_TOKEN_ELEMENT_END: + + // In this state, we are only expecting the Authentication Token Element. + if (strcmp(name, AUTH_TOKEN_ELEMENT_NAME) == 0) + { + // Good, advance to the next state. + pGetAuthTokenRespParse->state = AWAITING_ROOT_ELEMENT_END; + } + else + { + DbgTrace(0, "-GetAuthTokenRespEndElementHandler- Un-expected start element\n", 0); + XML_StopParser(pGetAuthTokenRespParse->p, XML_FALSE); + } + break; + + default: + DbgTrace(0, "-GetAuthTokenRespEndElementHandler- Un-expected state = %d\n", pGetAuthTokenRespParse->state); + XML_StopParser(pGetAuthTokenRespParse->p, XML_FALSE); + break; + } + + DbgTrace(2, "-GetAuthTokenRespEndElementHandler- End\n", 0); +} + + +//++======================================================================= +CasaStatus +CreateGetAuthTokenResp( + IN char *pRespMsg, + IN int respLen, + INOUT GetAuthTokenResp **ppGetAuthTokenResp) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus = CASA_STATUS_SUCCESS; + GetAuthTokenRespParse getAuthTokenRespParse = {0}; + GetAuthTokenResp *pGetAuthTokenResp; + + DbgTrace(1, "-CreateGetAuthTokenResp- Start\n", 0); + + /* + * When a get authentication token request is processed successfully, the + * server replies to the client with a message with the following format: + * + * + * + * ok200 + * lifetime valuesession token data + * + * + * When a get authentication token request fails to be successfully processed, + * the server responds with an error and an error description string. The message + * format of an unsuccessful reply is as follows: + * + * + * + * status descriptionstatus code + * + * + * Plase note that the protocol utilizes the status codes defined + * in the HTTP 1.1 Specification. + * + */ + + // Allocate GetAuthTokenResp object + pGetAuthTokenResp = malloc(sizeof(*pGetAuthTokenResp)); + if (pGetAuthTokenResp) + { + XML_Parser p; + + // Initialize the GetAuthTokenResp object and set it in the + // parse oject. + memset(pGetAuthTokenResp, 0, sizeof(*pGetAuthTokenResp)); + getAuthTokenRespParse.pGetAuthTokenResp = pGetAuthTokenResp; + + // Create parser + p = XML_ParserCreate(NULL); + if (p) + { + // Keep track of the parser in our parse object + getAuthTokenRespParse.p = p; + + // Initialize the status within the parse object + getAuthTokenRespParse.status = CASA_STATUS_SUCCESS; + + // Set the start and end element handlers + XML_SetElementHandler(p, + (XML_StartElementHandler) GetAuthTokenRespStartElementHandler, + (XML_EndElementHandler) GetAuthTokenRespEndElementHandler); + + // Set the character data handler + XML_SetCharacterDataHandler(p, (XML_CharacterDataHandler) GetAuthTokenRespCharDataHandler); + + + // Set our user data + XML_SetUserData(p, &getAuthTokenRespParse); + + // Parse the document + if (XML_Parse(p, pRespMsg, respLen, 1) == XML_STATUS_OK) + { + // Verify that the parse operation completed successfully + if (getAuthTokenRespParse.state == DONE_PARSING) + { + // The parse operation succeded, obtain the status returned + // by the server. + retStatus = getAuthTokenRespParse.status; + } + else + { + DbgTrace(0, "-CreateGetAuthTokenResp- Parse operation did not complete\n", 0); + + // Check if a status has been recorded + if (getAuthTokenRespParse.status != CASA_STATUS_SUCCESS) + { + retStatus = getAuthTokenRespParse.status; + } + else + { + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_PROTOCOL_ERROR); + } + } + } + else + { + DbgTrace(0, "-CreateGetAuthTokenResp- Parse error %d\n", XML_GetErrorCode(p)); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_PROTOCOL_ERROR); + } + + // Free the parser + XML_ParserFree(p); + } + else + { + DbgTrace(0, "-CreateGetAuthTokenResp- Parser creation error\n", 0); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + + // Return the AuthenticationResp object to the caller if necessary + if (CASA_SUCCESS(retStatus)) + { + *ppGetAuthTokenResp = pGetAuthTokenResp; + } + else + { + free(pGetAuthTokenResp); + } + } + else + { + DbgTrace(0, "-CreateGetAuthTokenResp- Memory allocation error\n", 0); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + DbgTrace(1, "-CreateGetAuthTokenResp- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +void +RelGetAuthTokenResp( + IN GetAuthTokenResp *pGetAuthTokenResp) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + DbgTrace(1, "-RelGetAuthTokenResp- Start\n", 0); + + // Free the resources associated with the object + if (pGetAuthTokenResp->pToken) + free(pGetAuthTokenResp->pToken); + + free(pGetAuthTokenResp); + + DbgTrace(1, "-RelGetAuthTokenResp- End\n", 0); +} + + +//++======================================================================= +//++======================================================================= +//++======================================================================= + diff --git a/CASA-auth-token/client/core/internal.h b/CASA-auth-token/client/core/internal.h new file mode 100644 index 00000000..11d9a779 --- /dev/null +++ b/CASA-auth-token/client/core/internal.h @@ -0,0 +1,437 @@ +/*********************************************************************** + * + * 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 + * + ***********************************************************************/ + +#ifndef _INTERNAL_H_ +#define _INTERNAL_H_ + +//===[ Include files ]===================================================== + +#include "platform.h" +#include +#include +#include +#include +#include "list_entry.h" +#include "config_if.h" +#include "mech_if.h" +#include "proto.h" + +//===[ Type definitions ]================================================== + +// +// Authentication Context structure +// +typedef struct _AuthContext +{ + LIST_ENTRY listEntry; + char *pContext; + int contextLen; + char *pMechanism; + int mechanismLen; + char *pMechInfo; + int mechInfoLen; + +} AuthContext, *PAuthContext; + +// +// Authentication Policy structure +// +typedef struct _AuthPolicy +{ + LIST_ENTRY authContextListHead; + +} AuthPolicy, *PAuthPolicy; + +// +// Get Authentication Policy Response structure +// +typedef struct _GetAuthPolicyResp +{ + char *pPolicy; + int policyLen; + +} GetAuthPolicyResp, *PGetAuthPolicyResp; + +// +// Get Authentication Token Response structure +// +typedef struct _GetAuthTokenResp +{ + char *pToken; + int tokenLen; + int tokenLifetime; + +} GetAuthTokenResp, *PGetAuthTokenResp; + +// +// Authenticate Response structure +// +typedef struct _AuthenticateResp +{ + char *pToken; + int tokenLen; + int tokenLifetime; + +} AuthenticateResp, *PAuthenticateResp; + +// +// Auth Cache Entry definition +// +typedef struct _AuthCacheEntry +{ + int status; + DWORD creationTime; + DWORD expirationTime; + bool doesNotExpire; + char token[1]; + +} AuthCacheEntry, *PAuthCacheEntry; + + +//===[ Inlines functions ]=============================================== + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + +//===[ Global externals ]================================================== + +extern int DebugLevel; + +extern char clientConfigFolder[]; + +extern char mechConfigFolder[]; + +extern char pathCharString[]; + + +//===[ External prototypes ]=============================================== + +// +// Functions exported by engine.c +// + +extern +CasaStatus +ObtainAuthTokenInt( + IN const char *pServiceName, + IN const char *pHostName, + INOUT char *pAuthTokenBuf, + INOUT int *pAuthTokenBufLen, + IN void *pCredStoreScope); + +// +// Functions exported by authmech.c +// + +extern +CasaStatus +GetAuthMechToken( + IN AuthContext *pAuthContext, + IN const char *pHostName, + IN void *pCredStoreScope, + INOUT char **ppAuthMechToken); + +// +// Functions exported by getpolicymsg.c +// + +extern +char* +BuildGetAuthPolicyMsg( + IN const char *pServiceName, + IN const char *pHostName); + +extern +CasaStatus +CreateGetAuthPolicyResp( + IN char *pRespMsg, + IN int respLen, + INOUT GetAuthPolicyResp **ppGetAuthPolicyResp); + +extern +void +RelGetAuthPolicyResp( + IN GetAuthPolicyResp *pGetAuthPolicyResp); + +// +// Functions exported by authpolicy.c +// + +extern +CasaStatus +CreateAuthPolicy( + IN char *pEncodedData, + IN int encodedDataLen, + INOUT AuthPolicy **ppAuthPolicy); + +extern +void +RelAuthPolicy( + IN AuthPolicy *pAuthPolicy); + +// +// Functions exported by authmsg.c +// + +extern +char* +BuildAuthenticateMsg( + IN AuthContext *pAuthContext, + IN char *pAuthMechToken); + +extern +CasaStatus +CreateAuthenticateResp( + IN char *pRespMsg, + IN int respLen, + INOUT AuthenticateResp **ppAuthenticateResp); + +extern +void +RelAuthenticateResp( + IN AuthenticateResp *pAuthenticateResp); + +// +// Functions exported by gettokenmsg.c +// + +extern +char* +BuildGetAuthTokenMsg( + IN const char *pServiceName, + IN const char *pHostName, + IN char *pSessionToken); + +extern +CasaStatus +CreateGetAuthTokenResp( + IN char *pRespMsg, + IN int respLen, + INOUT GetAuthTokenResp **ppGetAuthTokenResp); + +extern +void +RelGetAuthTokenResp( + IN GetAuthTokenResp *pGetAuthTokenResp); + +// +// Functions exported by cache.c +// + +extern +AuthCacheEntry* +CreateSessionTokenCacheEntry( + IN const char *pCacheKey, + IN CasaStatus status, + IN char *pToken, + IN int entryLifetime, + IN void *pCredStoreScope); + +extern +AuthCacheEntry* +CreateAuthTokenCacheEntry( + IN const char *pCacheKey, + IN const char *pHostName, + IN CasaStatus status, + IN char *pToken, + IN int entryLifetime, + IN void *pCredStoreScope); + +extern +void +FreeAuthCacheEntry( + IN AuthCacheEntry *pEntry); + +extern +AuthCacheEntry* +FindSessionTokenEntryInCache( + IN const char *pCacheKey, + IN void *pCredStoreScope); + +extern +AuthCacheEntry* +FindAuthTokenEntryInCache( + IN const char *pCacheKey, + IN const char *pGroupOrHostName, + IN void *pCredStoreScope); + +extern +CasaStatus +InitializeAuthCache(void); + +// +// Functions exported by config.c +// + +extern +CasaStatus +GetConfigInterface( + IN const char *pConfigFolder, + IN const char *pConfigName, + INOUT ConfigIf **ppConfigIf); + +// +// Functions exported by platform.c +// + +extern +CasaStatus +CreateUserMutex( + HANDLE *phMutex + ); + +extern +void +AcquireUserMutex( + HANDLE hMutex + ); + +extern +void +ReleaseUserMutex( + HANDLE hMutex + ); + +extern +void +DestroyUserMutex( + HANDLE hMutex + ); + +extern +LIB_HANDLE +OpenLibrary( + IN char *pFileName); + +extern +void +CloseLibrary( + IN LIB_HANDLE libHandle); + +extern +void* +GetFunctionPtr( + IN LIB_HANDLE libHandle, + IN char *pFunctionName); + +extern +char* +NormalizeHostName( + IN const char *pHostName); + +extern +CasaStatus +InitializeHostNameNormalization(void); + +// +// Functions exported by rpc.c +// + +extern +RpcSession* +OpenRpcSession( + IN const char *pHostName, + IN const uint16_t hostPort); + +extern +void +CloseRpcSession( + IN RpcSession *pSession); + +#define SECURE_RPC_FLAG 1 +#define ALLOW_INVALID_CERTS_RPC_FLAG 2 +#define ALLOW_INVALID_CERTS_USER_APPROVAL_RPC_FLAG 4 + +extern +CasaStatus +Rpc( + IN RpcSession *pSession, + IN char *pMethod, + IN long flags, + IN char *pRequestData, + INOUT char **ppResponseData, + INOUT int *pResponseDataLen); + +extern +CasaStatus +InitializeRpc(void); + +// +// Functions exported by utils.c +// + +extern +CasaStatus +EncodeData( + IN const void *pData, + IN const int32_t dataLen, + INOUT char **ppEncodedData, + INOUT int32_t *pEncodedDataLen); + +extern +CasaStatus +DecodeData( + IN const char *pEncodedData, + IN const int32_t encodedDataLen, // Does not include NULL terminator + INOUT void **ppData, + INOUT int32_t *pDataLen); + +extern +int +dtoul( + IN const char *cp, + IN const int len); + +// +// Functions exported by invalidcert.c +// + +extern +bool +InvalidCertsFromHostAllowed( + IN char *pHostName); + +extern +void +AllowInvalidCertsFromHost( + IN char *pHostName); + +#define INVALID_CERT_CA_FLAG 1 +#define INVALID_CERT_CN_FLAG 2 +#define INVALID_CERT_DATE_FLAG 4 + +extern +bool +UserApprovedCert( + IN char *pHostName, + IN char *pCertSubject, + IN char *pCertIssuer, + IN long invalidCertFlags); + + +//========================================================================= + +#endif // _INTERNAL_H_ + diff --git a/CASA-auth-token/client/core/invalidcert.c b/CASA-auth-token/client/core/invalidcert.c new file mode 100644 index 00000000..a4a4fb63 --- /dev/null +++ b/CASA-auth-token/client/core/invalidcert.c @@ -0,0 +1,140 @@ +/*********************************************************************** + * + * 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 + * + ***********************************************************************/ + + +//===[ Include files ]===================================================== + +#include "internal.h" + +//===[ Type definitions ]================================================== + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + +//++======================================================================= +bool +InvalidCertsFromHostAllowed( + IN char *pHostName) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L0 +//=======================================================================-- +{ + bool retStatus = false; + + DbgTrace(2, "-InvalidCertsFromHostAllowed- Start\n", 0); + + // tbd + + DbgTrace(2, "-InvalidCertsFromHostAllowed- End, retStatus = %0X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +void +AllowInvalidCertsFromHost( + IN char *pHostName) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L0 +//=======================================================================-- +{ + bool retStatus = true; + + DbgTrace(2, "-AllowInvalidCertsFromHost- Start\n", 0); + + // tbd + + DbgTrace(2, "-AllowInvalidCertsFromHost- End\n", 0); +} + + +//++======================================================================= +bool +UserApprovedCert( + IN char *pHostName, + IN char *pCertSubject, + IN char *pCertIssuer, + IN long invalidCertFlags) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L0 +//=======================================================================-- +{ + bool retStatus = false; + + DbgTrace(2, "-UserApprovedCert- Start\n", 0); + + // tbd + + if (invalidCertFlags & INVALID_CERT_CN_FLAG) + { + DbgTrace(0, "-UserApprovedCert- Invalid Cert from Host = %s\n", pHostName); + } + if (invalidCertFlags & INVALID_CERT_CA_FLAG) + { + DbgTrace(0, "-UserApprovedCert- Invalid CA in Cert from Host = %s\n", pHostName); + } + if (invalidCertFlags & INVALID_CERT_DATE_FLAG) + { + DbgTrace(0, "-UserApprovedCert- Invalid DATE in Cert from Host = %s\n", pHostName); + } + DbgTrace(0, "-UserApprovedCert- Approving Invalid Cert from Host = %s\n", pHostName); + DbgTrace(0, "-UserApprovedCert- Invalid Cert Subject = %s\n", pCertSubject); + DbgTrace(0, "-UserApprovedCert- Invalid Cert Issuer = %s\n", pCertIssuer); + + DbgTrace(2, "-UserApprovedCert- End, retStatus = %0X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +//++======================================================================= +//++======================================================================= + diff --git a/CASA-auth-token/client/core/linux/Makefile.am b/CASA-auth-token/client/core/linux/Makefile.am new file mode 100644 index 00000000..36347e62 --- /dev/null +++ b/CASA-auth-token/client/core/linux/Makefile.am @@ -0,0 +1,126 @@ +####################################################################### +# +# 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 +# +####################################################################### + +if DEBUG +TARGET_CFG = Debug +CFLAGS += -v -w +DEFINES = -DDBG +else +TARGET_CFG = Release +DEFINES = -DNDEBUG +endif + +SUBDIRS = + +DIST_SUBDIRS = + +ROOT = ../.. + +LIBDIR = $(ROOT)/$(LIB) + +# handle Mono secondary dependencies +export MONO_PATH := $(MONO_PATH) + +PLATFORMINDEPENDENTSOURCEDIR = .. +PLATFORMDEPENDENTSOURCEDIR = . + +MODULE_NAME = libcasa_c_authtoken +MODULE_EXT = so + +CFILES = ../authmech.c \ + ../authmsg.c \ + ../authpolicy.c \ + ../cache.c \ + ../config.c \ + ../engine.c \ + ../getpolicymsg.c \ + ../gettokenmsg.c \ + ../util.c \ + ../invalidcert.c \ + rpc.c \ + platform.c + +CSFILES_CSC := +INCLUDES = -I. -I.. -I../../include +RESOURCES = + +if LIB64 +DEFINES += -D_LIB64 +endif + +CFLAGS += -Wno-format-extra-args -fno-strict-aliasing $(INCLUDES) $(DEFINES) +LIBS = -lpthread -ldl -lexpat -lcurl -lidn -lssl -lcrypto -lz -lmicasa +LDFLAGS = -Bsymbolic -shared -Wl,-soname=$(MODULE_NAME).$(MODULE_EXT) -L$(ROOT)/lib/$(TARGET_CFG) + +OBJDIR = ./$(TARGET_CFG)/$(LIB) +OBJS = $(addprefix $(OBJDIR)/, $(CFILES:%.c=%.o)) + +EXTRA_DIST = $(CFILES) *.h + +CUR_DIR := $(shell pwd) + +all: $(OBJDIR)/$(MODULE_NAME).$(MODULE_EXT) + +# +# Pattern based rules. +# +vpath %.c $(PLATFORMDEPENDENTSOURCEDIR) $(PLATFORMINDEPENDENTSOURCEDIR) +vpath %.cpp $(PLATFORMDEPENDENTSOURCEDIR) $(PLATFORMINDEPENDENTSOURCEDIR) + +$(OBJDIR)/%.o: %.c + $(CC) -c $(CFLAGS) -o $@ $< + +$(OBJDIR)/%.o: %.cpp + $(CC) -c $(CFLAGS) -o $@ $< + +$(OBJDIR)/$(MODULE_NAME).$(MODULE_EXT): $(OBJDIR) $(OBJS) + @echo [======== Linking $@ ========] + $(LINK) -o $@ $(LDFLAGS) $(OBJS) $(LIBS) + cp -f $(OBJDIR)/$(MODULE_NAME).$(MODULE_EXT) $(LIBDIR)/$(TARGET_CFG)/$(MODULE_NAME).$(MODULE_EXT) + +$(OBJDIR): + [ -d $(OBJDIR) ] || mkdir -p $(OBJDIR) + [ -d $(LIBDIR) ] || mkdir -p $(LIBDIR) + [ -d $(LIBDIR)/$(TARGET_CFG) ] || mkdir -p $(LIBDIR)/$(TARGET_CFG) + + +install-exec-local: $(OBJDIR)/$(MODULE_NAME).$(MODULE_EXT) + $(mkinstalldirs) $(DESTDIR)$(libdir) + $(INSTALL_PROGRAM) $(OBJDIR)/$(MODULE_NAME).$(MODULE_EXT) $(DESTDIR)$(libdir)/ + +uninstall-local: + cd $(DESTDIR)$(libdir); rm -f $(OBJDIR)/$(MODULE_NAME).$(MODULE_EXT) + rmdir $(DESTDIR)$(libdir) + +#installcheck-local: install +# $(mkinstalldirs) $(DESTDIR)$(libdir) +# $(INSTALL_PROGRAM) $(DESTDIR)$(libdir) +# cd $(DESTDIR)$(libdir); $(MONO) + +clean-local: + if [ -d $(TARGET_CFG) ]; then rm -rf $(TARGET_CFG); fi + +distclean-local: + +maintainer-clean-local: + rm -f Makefile.in + diff --git a/CASA-auth-token/client/core/linux/platform.c b/CASA-auth-token/client/core/linux/platform.c new file mode 100644 index 00000000..32482f8d --- /dev/null +++ b/CASA-auth-token/client/core/linux/platform.c @@ -0,0 +1,831 @@ +/*********************************************************************** + * + * 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 + * + ***********************************************************************/ + +//===[ Include files ]===================================================== + +#include "internal.h" + +//===[ Type definitions ]================================================== + +// +// Normalized Host Name Cache Entry definition +// +typedef struct _NormalizedHostNameCacheEntry +{ + LIST_ENTRY listEntry; + char *pHostName; + char *pNormalizedHostName; + int buffLengthRequired; + +} NormalizedHostNameCacheEntry, *PNormalizedHostNameCacheEntry; + + +//===[ Type definitions for Local_sem ]==================================== +// +// Notes: Most of the code for this definitions and the Local_sem_xxxx +// functions was copied with minor modifications from W. Richard +// Stevens book: UNIX Network Programming, Interprocess +// Communications (Printed in 1999). +// +// You may ask, why not just use Posix Named Semaphores? The answer +// is that I wish that I could but I can not tolerate that they are +// not released when the process that holds them terminates abnormally. +// + +union semun /* define union for semctl() */ +{ + int val; + struct semid_ds *buf; + unsigned short *array; +}; + +typedef struct +{ + int sem_semid; /* the System V semaphore ID */ + int sem_magic; /* magic number if open */ + +} Local_sem_t; + +#ifndef SEM_R +#define SEM_R 0400 +#endif + +#ifndef SEM_A +#define SEM_A 0200 +#endif + +#define SVSEM_MODE (SEM_R | SEM_A | SEM_R>>3 | SEM_R>>6) + +#define SEM_MAGIC 0x45678923 + +#define SEM_FAILED ((Local_sem_t *)(-1)) /* avoid compiler warnings */ + +#ifndef SEMVMX +#define SEMVMX 32767 /* historical System V max value for sem */ +#endif + +#define MAX_OPEN_SEM_TRIES 10 /* for waiting for initialization */ + + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + +// Normalized host name cache variables +static +LIST_ENTRY normalizedHostNameCacheListHead; + +static +pthread_mutex_t g_hNormalizedHostNameCacheMutex = PTHREAD_MUTEX_INITIALIZER; + +// Client configuration file folder +char clientConfigFolder[] = "/etc/CASA/authtoken/client"; + +// Authentication mechanism configuration file folder +char mechConfigFolder[] = "/etc/CASA/authtoken/client/mechanisms"; + +// Module Synchronization mutex +pthread_mutex_t g_hModuleMutex = PTHREAD_MUTEX_INITIALIZER; + +// Path separator +char pathCharString[] = "/"; + +// Milliseconds per System Tick +static +long g_milliSecondsPerTicks = 0; + +// Named Semaphore for user variables +static +char g_userNamedSemName[256]; + +static +Local_sem_t *g_userNamedSem = SEM_FAILED; + +static +bool g_userNamedSemAcquired = false; + + +//++======================================================================= +Local_sem_t* +Local_sem_open(const char *pathname, int oflag, ... ) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: Most of the code for this routine was copied with minor +// modifications from W. Richard Stevens book: UNIX Network +// Programming, Interprocess Communications (Printed in 1999). +// +// L2 +//=======================================================================-- +{ + int i, fd, semflag, semid, save_errno; + key_t key; + mode_t mode; + va_list ap; + Local_sem_t *sem; + union semun arg; + unsigned int value; + struct semid_ds seminfo; + struct sembuf initop; + + /* 4no mode for sem_open() w/out O_CREAT; guess */ + semflag = SVSEM_MODE; + semid = -1; + + if (oflag & O_CREAT) { + va_start(ap, oflag); /* init ap to final named argument */ + mode = va_arg(ap, mode_t); + value = va_arg(ap, unsigned int); + va_end(ap); + + /* 4convert to key that will identify System V semaphore */ + if ( (fd = open(pathname, oflag, mode)) == -1) + return(SEM_FAILED); + close(fd); + if ( (key = ftok(pathname, 0)) == (key_t) -1) + return(SEM_FAILED); + + semflag = IPC_CREAT | (mode & 0777); + if (oflag & O_EXCL) + semflag |= IPC_EXCL; + + /* 4create the System V semaphore with IPC_EXCL */ + if ( (semid = semget(key, 1, semflag | IPC_EXCL)) >= 0) { + /* 4success, we're the first so initialize to 0 */ + arg.val = 0; + if (semctl(semid, 0, SETVAL, arg) == -1) + goto err; + /* 4then increment by value to set sem_otime nonzero */ + if (value > SEMVMX) { + errno = EINVAL; + goto err; + } + initop.sem_num = 0; + initop.sem_op = value; + initop.sem_flg = 0; + if (semop(semid, &initop, 1) == -1) + goto err; + goto finish; + + } else if (errno != EEXIST || (semflag & IPC_EXCL) != 0) + goto err; + /* else fall through */ + } + + /* + * (O_CREAT not secified) or + * (O_CREAT without O_EXCL and semaphore already exists). + * Must open semaphore and make certain it has been initialized. + */ + if ( (key = ftok(pathname, 0)) == (key_t) -1) + goto err; + if ( (semid = semget(key, 0, semflag)) == -1) + goto err; + + arg.buf = &seminfo; + for (i = 0; i < MAX_OPEN_SEM_TRIES; i++) { + if (semctl(semid, 0, IPC_STAT, arg) == -1) + goto err; + if (arg.buf->sem_otime != 0) + goto finish; + sleep(1); + } + errno = ETIMEDOUT; +err: + save_errno = errno; /* don't let semctl() change errno */ + if (semid != -1) + semctl(semid, 0, IPC_RMID); + errno = save_errno; + return(SEM_FAILED); + +finish: + if ( (sem = malloc(sizeof(Local_sem_t))) == NULL) + goto err; + sem->sem_semid = semid; + sem->sem_magic = SEM_MAGIC; + return(sem); +} + + +//++======================================================================= +int +Local_sem_wait(Local_sem_t *sem) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: Most of the code for this routine was copied with minor +// modifications from W. Richard Stevens book: UNIX Network +// Programming, Interprocess Communications (Printed in 1999). +// +// L2 +//=======================================================================-- +{ + struct sembuf op; + + if (sem->sem_magic != SEM_MAGIC) { + errno = EINVAL; + return(-1); + } + + op.sem_num = 0; + op.sem_op = -1; + //op.sem_flg = 0; + op.sem_flg = SEM_UNDO; // Deviation from Richard's to allow cleanup in case of abnormal termination. + if (semop(sem->sem_semid, &op, 1) < 0) + return(-1); + return(0); +} + + +//++======================================================================= +int +Local_sem_post(Local_sem_t *sem) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: Most of the code for this routine was copied with minor +// modifications from W. Richard Stevens book: UNIX Network +// Programming, Interprocess Communications (Printed in 1999). +// +// L2 +//=======================================================================-- +{ + struct sembuf op; + + if (sem->sem_magic != SEM_MAGIC) { + errno = EINVAL; + return(-1); + } + + op.sem_num = 0; + op.sem_op = 1; + op.sem_flg = 0; + if (semop(sem->sem_semid, &op, 1) < 0) + return(-1); + return(0); +} + + +//++======================================================================= +int +Local_sem_close(Local_sem_t *sem) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: Most of the code for this routine was copied with minor +// modifications from W. Richard Stevens book: UNIX Network +// Programming, Interprocess Communications (Printed in 1999). +// +// L2 +//=======================================================================-- +{ + if (sem->sem_magic != SEM_MAGIC) { + errno = EINVAL; + return(-1); + } + sem->sem_magic = 0; /* just in case */ + + free(sem); + return(0); +} + + +//++======================================================================= +DWORD +GetTickCount(void) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + struct tms tm; + DWORD tickCount; + + DbgTrace(2, "-GetTickCount- Start\n", 0); + + // Determine milliseconds per tick if we have not done already + if (g_milliSecondsPerTicks == 0) + { + long ticksPerSecond; + + ticksPerSecond = sysconf(_SC_CLK_TCK); + DbgTrace(3, "-GetTickCount- TicksPerSec = %0lX\n", ticksPerSecond); + g_milliSecondsPerTicks = 1000 / ticksPerSecond; + } + + // Determine the tickCount as milliseconds + tickCount = g_milliSecondsPerTicks * times(&tm); + + DbgTrace(2, "-GetTickCount- End, retValue = %0lX\n", tickCount); + + return tickCount; +} + + +//++======================================================================= +CasaStatus +CreateUserMutex( + HANDLE *phMutex + ) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_UNSUCCESSFUL); + + DbgTrace(1, "-CreateUserMutex- Start\n", 0); + + // We use Named Semaphores to provide this functionality. The semaphore names are + // linked to the user via its uid. + if (sprintf(g_userNamedSemName, "/var/lib/CASA/authtoken/semuser_%d", geteuid()) != -1) + { + // Create or open semaphore to be only used by the effective user + g_userNamedSem = Local_sem_open((const char*) g_userNamedSemName, O_RDWR | O_CREAT, 0600, 1); + if (g_userNamedSem == SEM_FAILED) + { + DbgTrace(0, "-CreateUserMutex- Error opening named semaphore, errno = %d\n", errno); + } + else + { + // Success + retStatus = CASA_STATUS_SUCCESS; + } + } + else + { + DbgTrace(0, "-CreateUserMutex- sprintf failed, error = %d\n", errno); + } + + DbgTrace(1, "-CreateUserMutex- End, retStatus\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +void +AcquireUserMutex( + HANDLE hMutex + ) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + DbgTrace(2, "-AcquireUserMutex- Start\n", 0); + + // Wait on the named semaphore + if (Local_sem_wait(g_userNamedSem) != 0) + { + DbgTrace(0, "-AcquireUserMutex- Error returned by sem_wait(), errno = %d\n", errno); + } + + // The user semaphore has been acquired + g_userNamedSemAcquired = true; + + DbgTrace(2, "-AcquireUserMutex- End\n", 0); +} + + +//++======================================================================= +void +ReleaseUserMutex( + HANDLE hMutex + ) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + DbgTrace(2, "-ReleaseUserMutex- Start\n", 0); + + // The user semaphore is no longer acquired + g_userNamedSemAcquired = false; + + // Post on the named semaphore + if (Local_sem_post(g_userNamedSem) != 0) + { + DbgTrace(0, "-ReleaseUserMutex- Error returned by sem_post(), errno = %d\n", errno); + } + + DbgTrace(2, "-ReleaseUserMutex- End\n", 0); +} + + +//++======================================================================= +void +DestroyUserMutex( + HANDLE hMutex + ) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + DbgTrace(2, "-DestroyUserMutex- Start\n", 0); + + // Do not do anything if the named semaphore is invalid + if (g_userNamedSem != SEM_FAILED) + { + // Close the named semaphore. Note that we want user semaphores to + // hang around, therefore we will not unlink them. This is per-design as + // is not a resource leak. If someone has an issue with this, then it can + // be solved by installing a cron job that cleans up the semaphores for + // deleted users. + if (Local_sem_close(g_userNamedSem) != 0) + { + DbgTrace(0, "-DestroyUserMutex- Error returned by sem_close(), errno = %d\n", errno); + } + + // Forget about the semaphore + g_userNamedSem = SEM_FAILED; + } + + DbgTrace(2, "-DestroyUserMutex- End\n", 0); +} + + +//++======================================================================= +LIB_HANDLE +OpenLibrary( + IN char *pFileName) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + LIB_HANDLE libHandle; + + DbgTrace(1, "-OpenLibrary- Start\n", 0); + + libHandle = dlopen(pFileName, RTLD_LAZY); + if (libHandle == NULL) + { + DbgTrace(0, "-OpenLibrary- Not able to load library, error = %s\n", dlerror()); + } + + DbgTrace(1, "-OpenLibrary- End, handle = %0lX\n", (long) libHandle); + + return libHandle; +} + + +//++======================================================================= +void +CloseLibrary( + IN LIB_HANDLE libHandle) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + DbgTrace(1, "-CloseLibrary- Start\n", 0); + + dlclose(libHandle); + + DbgTrace(1, "-CloseLibrary- End\n", 0); +} + + +//++======================================================================= +void* +GetFunctionPtr( + IN LIB_HANDLE libHandle, + IN char *pFunctionName) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + void *pFuncPtr; + + DbgTrace(1, "-GetFunctionPtr- Start\n", 0); + + pFuncPtr = dlsym(libHandle, pFunctionName); + if (pFuncPtr == NULL) + { + DbgTrace(0, "-GetFunctionPtr- Not able to obtain func ptr, error = %s\n", dlerror()); + } + + DbgTrace(1, "-GetFunctionPtr- End, pFuncPtr = %0lX\n", (long) pFuncPtr); + + return pFuncPtr; +} + + +//++======================================================================= +char* +NormalizeHostName( + IN const char *pHostName) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + char *pNormalizedName = NULL; + LIST_ENTRY *pListEntry; + NormalizedHostNameCacheEntry *pEntry = NULL; + + DbgTrace(1, "-NormalizeHostName- Start\n", 0); + + // Obtain our synchronization mutex + pthread_mutex_lock(&g_hNormalizedHostNameCacheMutex); + + // First try to find an entry in the normalized host name cache + // for the host name provided. + pListEntry = normalizedHostNameCacheListHead.Flink; + while (pListEntry != &normalizedHostNameCacheListHead) + { + // Get pointer to the entry + pEntry = CONTAINING_RECORD(pListEntry, NormalizedHostNameCacheEntry, listEntry); + + // Check if the entry is for the host name + if (strcmp(pHostName, pEntry->pHostName) == 0) + { + // This entry corresponds to the given host name + break; + } + else + { + // The entry does not correspond to the given host name + pEntry = NULL; + } + + // Advance to the next entry + pListEntry = pListEntry->Flink; + } + + // Check if we found an entry in our cache for the given host name + if (pEntry) + { + // Entry found, obtain the normalized name from it. + pNormalizedName = (char*) malloc(pEntry->buffLengthRequired); + if (pNormalizedName) + { + // Copy the normalized name onto the allocated buffer + strcpy(pNormalizedName, pEntry->pNormalizedHostName); + } + else + { + DbgTrace(0, "-NormalizeHostName- Buffer allocation error\n", 0); + } + } + else + { + // An entry was not found in our cache, create one. + pEntry = (NormalizedHostNameCacheEntry*) malloc(sizeof(NormalizedHostNameCacheEntry)); + if (pEntry) + { + // Zero the entry + memset(pEntry, 0, sizeof(*pEntry)); + + // Allocate a buffer to hold the host name in the entry + pEntry->pHostName = (char*) malloc(strlen(pHostName) + 1); + if (pEntry->pHostName) + { + struct hostent *pLookupResult; + struct sockaddr_in sockAddr = {0}; + + // Copy the host name given into the allocated buffer + strcpy(pEntry->pHostName, pHostName); + + // Now try to resolve the normalized name + pLookupResult = gethostbyname(pHostName); + if (pLookupResult && pLookupResult->h_addrtype == AF_INET) + { + char dnsHostName[NI_MAXHOST]; + + // Set up a sockaddr structure + sockAddr.sin_family = AF_INET; + sockAddr.sin_addr.s_addr = *((int*) pLookupResult->h_addr_list[0]); + + // Now try to resolve the name using DNS + if (getnameinfo((const struct sockaddr*) &sockAddr, + sizeof(sockAddr), + dnsHostName, + sizeof(dnsHostName), + NULL, + 0, + NI_NAMEREQD) == 0) + { + // We resolved the address to a DNS name, use it as the normalized name. + pEntry->buffLengthRequired = (int) strlen(dnsHostName) + 1; + pEntry->pNormalizedHostName = (char*) malloc(pEntry->buffLengthRequired); + if (pEntry->pNormalizedHostName) + { + // Copy the dns name + strcpy(pEntry->pNormalizedHostName, dnsHostName); + } + else + { + DbgTrace(0, "-NormalizeHostName- Buffer allocation error\n", 0); + } + } + else + { + DbgTrace(0, "-NormalizeHostName- getnameInfo failed, error %d\n", errno); + + // Not able to resolve the name in DNS, just use the host name as + // the normalized name. + pEntry->buffLengthRequired = (int) strlen(pHostName) + 1; + pEntry->pNormalizedHostName = (char*) malloc(pEntry->buffLengthRequired); + if (pEntry->pNormalizedHostName) + { + // Copy the host name + strcpy(pEntry->pNormalizedHostName, pHostName); + } + else + { + DbgTrace(0, "-NormalizeHostName- Buffer allocation error\n", 0); + } + } + } + else + { + DbgTrace(0, "-NormalizeHostName- Name resolution failed, error = %d\n", errno); + } + } + else + { + DbgTrace(0, "-NormalizeHostName- Buffer allocation error\n", 0); + + // Free the space allocated for the entry + free(pEntry); + } + + // Proceed based on whether or not we normalized the name + if (pEntry->pNormalizedHostName) + { + // The name was normalized, save the entry in our cache. + InsertHeadList(&normalizedHostNameCacheListHead, &pEntry->listEntry); + + // Return the normalized name present in the entry + pNormalizedName = (char*) malloc(pEntry->buffLengthRequired); + if (pNormalizedName) + { + // Copy the normalized name onto the allocated buffer + strcpy(pNormalizedName, pEntry->pNormalizedHostName); + } + else + { + DbgTrace(0, "-NormalizeHostName- Buffer allocation error\n", 0); + } + } + else + { + // The host name was not normalized, free allocated resources. + if (pEntry->pHostName) + free(pEntry->pHostName); + free(pEntry); + } + } + else + { + DbgTrace(0, "-NormalizeHostName- Buffer allocation error\n", 0); + } + } + + // Release our synchronization mutex + pthread_mutex_unlock(&g_hNormalizedHostNameCacheMutex); + + DbgTrace(1, "-NormalizeHostName- End, pNormalizedName = %0lX\n", (long) pNormalizedName); + + return pNormalizedName; +} + + +//++======================================================================= +CasaStatus +InitializeHostNameNormalization(void) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus = CASA_STATUS_SUCCESS; + + DbgTrace(1, "-InitializeHostNameNormalization- Start\n", 0); + + // Initialize the cache list head + InitializeListHead(&normalizedHostNameCacheListHead); + + DbgTrace(1, "-InitializeHostNameNormalization- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +//++======================================================================= +//++======================================================================= + diff --git a/CASA-auth-token/client/core/linux/platform.h b/CASA-auth-token/client/core/linux/platform.h new file mode 100644 index 00000000..db1b11b4 --- /dev/null +++ b/CASA-auth-token/client/core/linux/platform.h @@ -0,0 +1,130 @@ +/*********************************************************************** + * + * 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 + * + ***********************************************************************/ + +#define _GNU_SOURCE + +//===[ Include files ]===================================================== + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//===[ Type definitions ]================================================== + +#ifndef CONTAINING_RECORD +#define CONTAINING_RECORD(address, type, field) ((type *)( \ + (char*)(address) - \ + (char*)(&((type *)0)->field))) +#endif + +// +// DbgTrace macro define +// +#define DbgTrace(LEVEL, X, Y) { \ +char printBuff[256]; \ + if (LEVEL == 0 || DebugLevel >= LEVEL) \ + { \ + _snprintf(printBuff, sizeof(printBuff), X, Y); \ + fprintf(stderr, "CASA_AuthToken %s", printBuff); \ + } \ +} +/*#define DbgTrace(LEVEL, X, Y) { \ + if (LEVEL == 0 || DebugLevel >= LEVEL) \ + { \ + openlog("CASA_AuthToken", LOG_CONS | LOG_NOWAIT | LOG_ODELAY, LOG_USER); \ + syslog(LOG_USER | LOG_INFO, X, Y); \ + closelog(); \ + } \ +}*/ + + +// +// Rpc Session definition +// +typedef struct _RpcSession +{ + CURL *hCurl; + char *pPartialHttpUrl; + int partialHttpUrlLen; + char *pPartialHttpsUrl; + int partialHttpsUrlLen; + struct curl_slist *headers; + char *pRecvData; + int recvDataLen; + +} RpcSession, *PRpcSession; + + +// +// Other definitions +// +#define HANDLE void* +#define LIB_HANDLE void* +#define DWORD unsigned long + +#define AcquireModuleMutex pthread_mutex_lock(&g_hModuleMutex) +#define ReleaseModuleMutex pthread_mutex_unlock(&g_hModuleMutex) + +// +// Deal with function name mapping issues +// +#define _snprintf snprintf +#define stricmp strcasecmp + + +//===[ Inlines functions ]=============================================== + +//===[ Function prototypes ]=============================================== + +//===[ Global externals ]================================================== + +//===[ External prototypes ]=============================================== + +extern +DWORD +GetTickCount(void); + +//===[ External data ]===================================================== + +extern pthread_mutex_t g_hModuleMutex; + + +//========================================================================= + diff --git a/CASA-auth-token/client/core/linux/rpc.c b/CASA-auth-token/client/core/linux/rpc.c new file mode 100644 index 00000000..253dbaed --- /dev/null +++ b/CASA-auth-token/client/core/linux/rpc.c @@ -0,0 +1,566 @@ +/*********************************************************************** + * + * 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 + * + ***********************************************************************/ + + +//===[ Include files ]===================================================== + +#include "internal.h" + +//===[ Type definitions ]================================================== + +#define MAX_RPC_RETRIES 3 + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + + +//++======================================================================= +size_t +CurlWriteCallback( + IN void *pData, + IN size_t dataItemSz, + IN size_t numDataItems, + IN RpcSession *pSession) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + size_t dataConsumed = numDataItems; + + DbgTrace(1, "-CurlWriteCallback- Start\n", 0); + + // Consume the data by keeping a copy of the data. Note that we may have + // already consumed some data in which case we need to allocate a new + // buffer big enough to hold all of it. + if (pSession->pRecvData == NULL) + { + // We have not yet consumed receive data for the current Rpc + pSession->pRecvData = (char*) malloc(numDataItems * dataItemSz); + if (pSession->pRecvData) + { + // Consume the data + memcpy(pSession->pRecvData, pData, numDataItems * dataItemSz); + pSession->recvDataLen = numDataItems * dataItemSz; + } + else + { + DbgTrace(0, "-CurlWriteCallback- Buffer allocation error\n", 0); + dataConsumed = CURLE_WRITE_ERROR; // To abort RPC + } + } + else + { + // We have already consumed receive data for the current Rpc, append the new data to it. + char *pNewRecvDataBuf = (char*) malloc(pSession->recvDataLen + (numDataItems * dataItemSz)); + if (pNewRecvDataBuf) + { + memcpy(pNewRecvDataBuf, pSession->pRecvData, pSession->recvDataLen); + memcpy(pNewRecvDataBuf + pSession->recvDataLen, pData, numDataItems * dataItemSz); + pSession->recvDataLen += numDataItems * dataItemSz; + free(pSession->pRecvData); + pSession->pRecvData = pNewRecvDataBuf; + } + else + { + DbgTrace(0, "-CurlWriteCallback- Buffer allocation error\n", 0); + dataConsumed = CURLE_WRITE_ERROR; // To abort RPC + + // Forget about already consumed data + free(pSession->pRecvData); + pSession->pRecvData = NULL; + } + } + + DbgTrace(1, "-CurlWriteCallback- End\n", 0); + + return dataConsumed; +} + + +//++======================================================================= +RpcSession* +OpenRpcSession( + IN const char *pHostName, + IN const uint16_t hostPort) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + RpcSession *pSession = NULL; + char *pPartialHttpUrl = NULL; + char *pPartialHttpsUrl = NULL; + int hostNameLen = strlen(pHostName); + + DbgTrace(1, "-OpenRpcSession- Start\n", 0); + + // Build the partial URL strings that may be used with this session. + pPartialHttpUrl = (char*) malloc(7 /*"http://"*/ + hostNameLen + 34 /*":XXXX/CasaAuthTokenSvc/Rpc?method="*/ + 1 /*NULL Terminator*/); + pPartialHttpsUrl = (char*) malloc(8 /*"https://"*/ + hostNameLen + 34 /*":XXXX/CasaAuthTokenSvc/Rpc?method="*/ + 1 /*NULL Terminator*/); + if (pPartialHttpUrl && pPartialHttpsUrl) + { + sprintf(pPartialHttpUrl, "http://%s:%d/CasaAuthTokenSvc/Rpc?method=", pHostName, hostPort); + sprintf(pPartialHttpsUrl, "https://%s:%d/CasaAuthTokenSvc/Rpc?method=", pHostName, hostPort); + + // Allocate space for the session + pSession = (RpcSession*) malloc(sizeof(*pSession)); + if (pSession) + { + // Zero the session structure + memset(pSession, 0, sizeof(*pSession)); + + // Get a curl handle + pSession->hCurl = curl_easy_init(); + if (pSession->hCurl != NULL) + { + CURLcode result; + bool setOptError = false; + + // Set necessary options on the handle + if ((result = curl_easy_setopt(pSession->hCurl, CURLOPT_NOSIGNAL, 0)) != CURLE_OK) + { + DbgTrace(0, "-OpenRpcSession- Error setting CURLOPT_NOSIGNAL, code = %d\n", result); + setOptError = true; + } + + if ((result = curl_easy_setopt(pSession->hCurl, CURLOPT_USERAGENT, "CASA Client/1.0")) != CURLE_OK) + { + DbgTrace(0, "-OpenRpcSession- Error setting CURLOPT_USERAGENT, code = %d\n", result); + setOptError = true; + } + + if ((result = curl_easy_setopt(pSession->hCurl, CURLOPT_POST, 1)) != CURLE_OK) + { + DbgTrace(0, "-OpenRpcSession- Error setting CURLOPT_POST, code = %d\n", result); + setOptError = true; + } + + pSession->headers = curl_slist_append(pSession->headers, "Content-Type: text/html"); + pSession->headers = curl_slist_append(pSession->headers, "Expect:"); + if ((result = curl_easy_setopt(pSession->hCurl, CURLOPT_HTTPHEADER, pSession->headers)) != CURLE_OK) + { + DbgTrace(0, "-OpenRpcSession- Error setting CURLOPT_HTTPHEADER, code = %d\n", result); + setOptError = true; + } + + if ((result = curl_easy_setopt(pSession->hCurl, CURLOPT_WRITEFUNCTION, CurlWriteCallback)) != CURLE_OK) + { + DbgTrace(0, "-OpenRpcSession- Error setting CURLOPT_WRITEFUNCTION, code = %d\n", result); + setOptError = true; + } + + if ((result = curl_easy_setopt(pSession->hCurl, CURLOPT_WRITEDATA, pSession)) != CURLE_OK) + { + DbgTrace(0, "-OpenRpcSession- Error setting CURLOPT_WRITEDATA, code = %d\n", result); + setOptError = true; + } + + // Now check if we succeded + if (setOptError == false) + { + // Success, finish setting up the session object. + pSession->pPartialHttpUrl = pPartialHttpUrl; + pSession->partialHttpUrlLen = strlen(pPartialHttpUrl); + pSession->pPartialHttpsUrl = pPartialHttpsUrl; + pSession->partialHttpsUrlLen = strlen(pPartialHttpsUrl); + + // Forget about the partial URL buffers so that they do not get deleted below + pPartialHttpUrl = NULL; + pPartialHttpsUrl = NULL; + } + else + { + // Failed to set a needed curl option + if (pSession->headers) + curl_slist_free_all(pSession->headers); + + curl_easy_cleanup(pSession->hCurl); + + free(pSession); + pSession = NULL; + } + } + else + { + DbgTrace(0, "-OpenRpcSession- Error creating curl handle\n", 0); + free(pSession); + pSession = NULL; + } + } + else + { + DbgTrace(0, "-OpenRpcSession- Failed to allocate buffer for rpc session\n", 0); + } + } + else + { + DbgTrace(0, "-OpenRpcSession- Failed to allocate buffer for URL\n", 0); + } + + // Free buffers not utilized + if (pPartialHttpUrl) + free(pPartialHttpUrl); + + if (pPartialHttpsUrl) + free(pPartialHttpsUrl); + + DbgTrace(2, "-OpenRpcSession- End, pSession = %0lX\n", (long) pSession); + + return pSession; +} + + +//++======================================================================= +void +CloseRpcSession( + IN RpcSession *pSession) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + DbgTrace(1, "-CloseRpcSession- Start\n", 0); + + // Free any HTTP headers associated with the session + if (pSession->headers) + curl_slist_free_all(pSession->headers); + + // Close the curl handle associated with this session + curl_easy_cleanup(pSession->hCurl); + + // Free the space allocated for the session + if (pSession->pRecvData) + free(pSession->pRecvData); + + free(pSession->pPartialHttpUrl); + free(pSession->pPartialHttpsUrl); + + free(pSession); + + DbgTrace(1, "-CloseRpcSession- End\n", 0); +} + + +//++======================================================================= +static +CasaStatus +InternalRpc( + IN RpcSession *pSession, + IN char *pMethod, + IN long flags, + IN char *pRequestData, + INOUT char **ppResponseData, + INOUT int *pResponseDataLen) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ +#define CASA_STATUS_INVALID_SERVER_CERTIFICATE CASA_STATUS_UNSUCCESSFUL // temporary until casa_status.h is updated + + CasaStatus retStatus; + char *pPartialUrl; + int partialUrlLen; + char *pUrl; + CURLcode curlResult; + + DbgTrace(1, "-InternalRpc- Start\n", 0); + + // Initialize output parameters + *ppResponseData = NULL; + *pResponseDataLen = 0; + + // Setup the URL using the input parameters + if (flags & SECURE_RPC_FLAG) + { + pPartialUrl = pSession->pPartialHttpsUrl; + partialUrlLen = pSession->partialHttpsUrlLen; + + // Check if we need to ignore invalid CERTS + if (flags & ALLOW_INVALID_CERTS_RPC_FLAG) + { + if ((curlResult = curl_easy_setopt(pSession->hCurl, CURLOPT_SSL_VERIFYPEER, 0)) != CURLE_OK) + { + DbgTrace(0, "-InternalRpc- Error setting CURLOPT_SSL_VERIFYPEER, code = %d\n", curlResult); + } + + if ((curlResult = curl_easy_setopt(pSession->hCurl, CURLOPT_SSL_VERIFYHOST, 0)) != CURLE_OK) + { + DbgTrace(0, "-InternalRpc- Error setting CURLOPT_SSL_VERIFYHOST, code = %d\n", curlResult); + } + } + else + { + if ((curlResult = curl_easy_setopt(pSession->hCurl, CURLOPT_SSL_VERIFYPEER, 1)) != CURLE_OK) + { + DbgTrace(0, "-InternalRpc- Error setting CURLOPT_SSL_VERIFYPEER, code = %d\n", curlResult); + } + + if ((curlResult = curl_easy_setopt(pSession->hCurl, CURLOPT_SSL_VERIFYHOST, 2)) != CURLE_OK) + { + DbgTrace(0, "-InternalRpc- Error setting CURLOPT_SSL_VERIFYHOST, code = %d\n", curlResult); + } + } + + } + else + { + pPartialUrl = pSession->pPartialHttpUrl; + partialUrlLen = pSession->partialHttpUrlLen; + } + + pUrl = (char*) malloc(partialUrlLen + strlen(pMethod) + 1); + + if (pUrl) + { + strcpy(pUrl, pPartialUrl); + strcat(pUrl, pMethod); + + // Tell curl about the URL + curlResult = curl_easy_setopt(pSession->hCurl, CURLOPT_URL, pUrl); + if (curlResult == CURLE_OK) + { + // Tell curl about our post data + curlResult = curl_easy_setopt(pSession->hCurl, CURLOPT_POSTFIELDS, pRequestData); + if (curlResult == CURLE_OK) + { + // Tell curl about our post data len + curlResult = curl_easy_setopt(pSession->hCurl, CURLOPT_POSTFIELDSIZE, strlen(pRequestData)); + if (curlResult == CURLE_OK) + { + // Now do the HTTP request + curlResult = curl_easy_perform(pSession->hCurl); + if (curlResult == CURLE_OK) + { + // Get the HTTP Response code + long httpCompStatus; + curlResult = curl_easy_getinfo(pSession->hCurl, CURLINFO_RESPONSE_CODE, &httpCompStatus); + if (curlResult == CURLE_OK) + { + // Verify that the HTTP request was successfully completed by the server + if (httpCompStatus == 200) + { + // Success, return the response data to the caller. + retStatus = CASA_STATUS_SUCCESS; + *ppResponseData = pSession->pRecvData; + *pResponseDataLen = pSession->recvDataLen;; + + // Forget about the response data buffer to keep from freeing it. + pSession->pRecvData = NULL; + } + else + { + DbgTrace(0, "-InternalRpc- HTTP request did not complete successfully, status = %ld\n", httpCompStatus); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_UNSUCCESSFUL); + } + } + else + { + DbgTrace(0, "-OpenRpcSession- Curl get info failed, code = %d\n", curlResult); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_UNSUCCESSFUL); + } + } + else + { + DbgTrace(0, "-OpenRpcSession- Curl perform failed, code = %d\n", curlResult); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_UNSUCCESSFUL); + } + + // Make sure that we never exit with a recv data buffer hanging off the session + if (pSession->pRecvData) + { + free(pSession->pRecvData); + pSession->pRecvData = NULL; + } + } + else + { + DbgTrace(0, "-OpenRpcSession- Error setting CURLOPT_POSTFIELDSIZE, code = %d\n", curlResult); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_UNSUCCESSFUL); + } + } + else + { + DbgTrace(0, "-OpenRpcSession- Error setting CURLOPT_POSTFIELDS, code = %d\n", curlResult); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_UNSUCCESSFUL); + } + } + else + { + DbgTrace(0, "-OpenRpcSession- Error setting CURLOPT_URL, code = %d\n", curlResult); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_UNSUCCESSFUL); + } + + // Free the buffer used to hold the URL + free(pUrl); + } + else + { + DbgTrace(0, "-InternalRpc- Buffer allocation failure\n", 0); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + + DbgTrace(1, "-InternalRpc- End, retStatus = %d\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +CasaStatus +Rpc( + IN RpcSession *pSession, + IN char *pMethod, + IN long flags, + IN char *pRequestData, + INOUT char **ppResponseData, + INOUT int *pResponseDataLen) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus; + int retries = 0; + + DbgTrace(1, "-Rpc- Start\n", 0); + + // Retry the RPC as needed + do + { + // Issue the RPC + retStatus = InternalRpc(pSession, + pMethod, + flags, + pRequestData, + ppResponseData, + pResponseDataLen); + + // Account for this try + retries ++; + + } while (CasaStatusCode(retStatus) == CASA_STATUS_AUTH_SERVER_UNAVAILABLE + && retries < MAX_RPC_RETRIES); + + DbgTrace(1, "-Rpc- End, retStatus = %d\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +CasaStatus +InitializeRpc(void) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus; + + DbgTrace(1, "-InitializeRpc- Start\n", 0); + + // Perform libcurl initializatoin + CURLcode curlStatus = curl_global_init(CURL_GLOBAL_SSL); + if (curlStatus != 0) + { + DbgTrace(0, "-InitializeRpc- Error initializing libcurl, curlStatus = %08X\n", curlStatus); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_UNSUCCESSFUL); + } + else + { + // Success + retStatus = CASA_STATUS_SUCCESS; + } + + DbgTrace(1, "-InitializeRpc- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +//++======================================================================= +//++======================================================================= + diff --git a/CASA-auth-token/client/core/mech_if.h b/CASA-auth-token/client/core/mech_if.h new file mode 100644 index 00000000..7a690005 --- /dev/null +++ b/CASA-auth-token/client/core/mech_if.h @@ -0,0 +1,184 @@ +/*********************************************************************** + * + * 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 + * + ***********************************************************************/ + + +#ifndef _MECH_IF_H_ +#define _MECH_IF_H_ + + +//===[ Include files ]===================================================== + +//===[ Type definitions ]================================================== + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + +/************************************************************************** +*************************************************************************** +** ** +** Authentication Mechanism Token Interface Definitions ** +** ** +*************************************************************************** +**************************************************************************/ + + +//++======================================================================= +typedef +int +(SSCS_CALL *PFNAuthTokenIf_AddReference)( + IN const void *pIfInstance); +// +// Arguments: +// pIfInstance - +// Pointer to interface object. +// +// Returns: +// Interface reference count. +// +// Description: +// Increases interface reference count. +//=======================================================================-- + + +//++======================================================================= +typedef +void +(SSCS_CALL *PFNAuthTokenIf_ReleaseReference)( + IN const void *pIfInstance); +// +// Arguments: +// pIfInstance - +// Pointer to interface object. +// +// Returns: +// Nothing. +// +// Description: +// Decreases interface reference count. The interface is deallocated if +// the reference count becomes zero. +//=======================================================================-- + + +//++======================================================================= +typedef +CasaStatus +(SSCS_CALL *PFNAuthTokenIf_GetAuthToken)( + IN const void *pIfInstance, + IN const char *pContext, + IN const char *pMechInfo, + IN const char *pHostName, + IN void *pCredStoreScope, + INOUT char *pTokenBuf, + INOUT int *pTokenBufLen); +// +// Arguments: +// pIfInstance - +// Pointer to interface object. +// +// pContext - +// Pointer to null terminated string containing mechanism specific +// context information. Another name for context is Authentication +// Realm. +// +// pMechInfo - +// Pointer to null terminated string containing mechanism specific +// information. This is information is provided by the server to +// aid the mechanism to generate an authentication token. For +// example, the mechanism information for a Kerberos mechanism +// may be the service principal name to which the user will be +// authenticating. +// +// pHostName - +// Pointer to null terminated string containing the name of the +// host where the ATS resides. +// +// pCredStoreScope - +// Pointer to CASA structure for scoping credential store access +// to specific users. This can only be leveraged when running in +// the context of System under Windows. +// +// pTokenBuf - +// Pointer to buffer that will receive the authentication +// token. The length of this buffer is specified by the +// pTokenBufLen parameter. Note that the the authentication +// token will be in the form of a NULL terminated string. +// +// pTokenBufLen - +// Pointer to integer that contains the length of the +// buffer pointed at by pTokenBuf. Upon return of the +// function, the integer will contain the actual length +// of the authentication token if the function successfully +// completes or the buffer length required if the function +// fails because the buffer pointed at by pUserNameBuf is +// not large enough. +// +// Returns: +// Casa Status +// +// Description: +// Get authentication token to authenticate user to specified service. +//=======================================================================-- + + +// +// AuthMechToken Interface Object +// +typedef struct _AuthTokenIf +{ + PFNAuthTokenIf_AddReference addReference; + PFNAuthTokenIf_ReleaseReference releaseReference; + PFNAuthTokenIf_GetAuthToken getAuthToken; + +} AuthTokenIf, *PAuthTokenIf; + + +//++======================================================================= +typedef +CasaStatus +(SSCS_CALL *PFN_GetAuthTokenIfRtn)( + IN const ConfigIf *pModuleConfigIf, + INOUT AuthTokenIf **ppAuthTokenIf); +// +// Arguments: +// pModuleConfigIf - +// Pointer to configuration interface instance for the module. +// +// ppAuthTokenIf - +// Pointer to variable that will receive pointer to AuthTokenIf +// instance. +// +// Returns: +// Casa Status +// +// Description: +// Gets authentication token interface instance. +//=======================================================================-- + +#define GET_AUTH_TOKEN_INTERFACE_RTN_SYMBOL "GetAuthTokenInterface" +#define GET_AUTH_TOKEN_INTERFACE_RTN GetAuthTokenInterface + + +#endif // #ifndef _MECH_IF_H_ + diff --git a/CASA-auth-token/client/core/mechanisms/Makefile.am b/CASA-auth-token/client/core/mechanisms/Makefile.am new file mode 100644 index 00000000..be130a11 --- /dev/null +++ b/CASA-auth-token/client/core/mechanisms/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 = krb5 pwd + +DIST_SUBDIRS = krb5 pwd + +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/client/core/mechanisms/krb5/Makefile.am b/CASA-auth-token/client/core/mechanisms/krb5/Makefile.am new file mode 100644 index 00000000..5abfab9d --- /dev/null +++ b/CASA-auth-token/client/core/mechanisms/krb5/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 = $(TARGET_OS) + +DIST_SUBDIRS = linux windows + +CFILES = *.c + +EXTRA_DIST = $(CFILES) *.h + +.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/client/core/mechanisms/krb5/README b/CASA-auth-token/client/core/mechanisms/krb5/README new file mode 100644 index 00000000..d2e696fd --- /dev/null +++ b/CASA-auth-token/client/core/mechanisms/krb5/README @@ -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 + * + ***********************************************************************/ +/*********************************************************************** + * + * README for krb5mech + * + ***********************************************************************/ + +INTRODUCTION + +krb5mech is a client authentication mechanism for the support of Kerberos 5 +authentication. The mechanism leverages the services of the native Kerberos 5 +client to obtain Kerberos Tokens that can be used for authenticating an entity +to a Kerberos service. + + +SECURITY CONSIDERATIONS + +The tokens that krb5mech generates are only utilized to authenticate the client +entity to the Kerberos service, because of this, auth_token relies on SSL for +server authentication. auth_token does not leverage the capabilities of GSSAPI +for data privacy and data integrity purposes. + + + + + + + + + + diff --git a/CASA-auth-token/client/core/mechanisms/krb5/TODO b/CASA-auth-token/client/core/mechanisms/krb5/TODO new file mode 100644 index 00000000..d3df377c --- /dev/null +++ b/CASA-auth-token/client/core/mechanisms/krb5/TODO @@ -0,0 +1,13 @@ +/*********************************************************************** + * + * TODO for krb5mech + * + ***********************************************************************/ + +INTRODUCTION + +This file contains a list of the items still outstanding for krb5mech. + +OUTSTANDING ITEMS + +None. diff --git a/CASA-auth-token/client/core/mechanisms/krb5/interface.c b/CASA-auth-token/client/core/mechanisms/krb5/interface.c new file mode 100644 index 00000000..2fbdf3f4 --- /dev/null +++ b/CASA-auth-token/client/core/mechanisms/krb5/interface.c @@ -0,0 +1,207 @@ +/*********************************************************************** + * + * 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 + * + ***********************************************************************/ + +//===[ Include files ]===================================================== + +#include "internal.h" + +//===[ Type definitions ]================================================== + +// +// Authentication Token Interface instance data +// +typedef struct _AuthTokenIfInstance +{ + int refCount; + AuthTokenIf authTokenIf; + +} AuthTokenIfInstance, *PAuthTokenIfInstance; + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + +// AuthTokenIf variables +static +int g_numAuthTokenIfObjs = 0; + + +//++======================================================================= +static +int SSCS_CALL +AuthTokenIf_AddReference( + IN const void *pIfInstance) +// +// Arguments: +// pIfInstance - +// Pointer to interface object. +// +// Returns: +// Interface reference count. +// +// Description: +// Increases interface reference count. +// +// L2 +//=======================================================================-- +{ + int refCount; + AuthTokenIfInstance *pAuthTokenIfInstance = CONTAINING_RECORD(pIfInstance, AuthTokenIfInstance, authTokenIf); + + DbgTrace(2, "-AuthTokenIf_AddReference- Start\n", 0); + + // Increment the reference count on the object + pAuthTokenIfInstance->refCount ++; + refCount = pAuthTokenIfInstance->refCount; + + DbgTrace(2, "-AuthTokenIf_AddReference- End, refCount = %08X\n", refCount); + + return refCount; +} + + +//++======================================================================= +static +void SSCS_CALL +AuthTokenIf_ReleaseReference( + IN const void *pIfInstance) +// +// Arguments: +// pIfInstance - +// Pointer to interface object. +// +// Returns: +// Nothing. +// +// Description: +// Decreases interface reference count. The interface is deallocated if +// the reference count becomes zero. +// +// L2 +//=======================================================================-- +{ + bool freeObj = false; + AuthTokenIfInstance *pAuthTokenIfInstance = CONTAINING_RECORD(pIfInstance, AuthTokenIfInstance, authTokenIf); + + DbgTrace(2, "-AuthTokenIf_ReleaseReference- Start\n", 0); + + // Decrement the reference count on the object and determine if it needs to + // be released. + pAuthTokenIfInstance->refCount --; + if (pAuthTokenIfInstance->refCount == 0) + { + // The object needs to be released, forget about it. + freeObj = true; + g_numAuthTokenIfObjs --; + } + + // Free object if necessary + if (freeObj) + free(pAuthTokenIfInstance); + + DbgTrace(2, "-AuthTokenIf_ReleaseReference- End\n", 0); +} + + +//++======================================================================= +CasaStatus SSCS_CALL +GET_AUTH_TOKEN_INTERFACE_RTN( + IN const ConfigIf *pModuleConfigIf, + INOUT AuthTokenIf **ppAuthTokenIf) +// +// Arguments: +// pModuleConfigIf - +// Pointer to configuration interface instance for the module. +// +// ppAuthTokenIf - +// Pointer to variable that will receive pointer to AuthTokenIf +// instance. +// +// Returns: +// Casa Status +// +// Description: +// Gets authentication token interface instance. +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus; + AuthTokenIfInstance *pAuthTokenIfInstance; + + + DbgTrace(1, "-GetAuthTokenInterface- Start\n", 0); + + // Validate input parameters + if (pModuleConfigIf == NULL + || ppAuthTokenIf == NULL) + { + DbgTrace(0, "-GetAuthTokenInterface- Invalid input parameter\n", 0); + + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_PWTOKEN, + CASA_STATUS_INVALID_PARAMETER); + goto exit; + } + + // Allocate space for the interface instance + pAuthTokenIfInstance = malloc(sizeof(*pAuthTokenIfInstance)); + if (pAuthTokenIfInstance) + { + // Initialize the interface instance data + pAuthTokenIfInstance->refCount = 1; + pAuthTokenIfInstance->authTokenIf.addReference = AuthTokenIf_AddReference; + pAuthTokenIfInstance->authTokenIf.releaseReference = AuthTokenIf_ReleaseReference; + pAuthTokenIfInstance->authTokenIf.getAuthToken = AuthTokenIf_GetAuthToken; + + // Keep track of this object + g_numAuthTokenIfObjs ++; + + // Return the interface to the caller + *ppAuthTokenIf = &pAuthTokenIfInstance->authTokenIf; + + // Success + retStatus = CASA_STATUS_SUCCESS; + } + else + { + DbgTrace(0, "-GetAuthTokenInterface- Buffer allocation failure\n", 0); + + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_PWTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + +exit: + + DbgTrace(1, "-GetAuthTokenInterface- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +//++======================================================================= +//++======================================================================= + diff --git a/CASA-auth-token/client/core/mechanisms/krb5/internal.h b/CASA-auth-token/client/core/mechanisms/krb5/internal.h new file mode 100644 index 00000000..4a7fa49f --- /dev/null +++ b/CASA-auth-token/client/core/mechanisms/krb5/internal.h @@ -0,0 +1,92 @@ +/*********************************************************************** + * + * 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 + * + ***********************************************************************/ + +#ifndef _INTERNAL_H_ +#define _INTERNAL_H_ + +//===[ Include files ]===================================================== + +#include "platform.h" +#include +#include +#include "config_if.h" +#include "mech_if.h" + +//===[ Type definitions ]================================================== + +//===[ Inlines functions ]=============================================== + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + +//===[ Global externals ]================================================== + +extern int DebugLevel; + +//===[ External prototypes ]=============================================== + +// +// Defined in get.c +// + +extern +CasaStatus SSCS_CALL +AuthTokenIf_GetAuthToken( + IN const void *pIfInstance, + IN const char *pContext, + IN const char *pMechInfo, + IN const char *pHostName, + IN void *pCredStoreScope, + INOUT char *pTokenBuf, + INOUT int *pTokenBufLen); + +extern +int +InitializeLibrary(void); + +// +// Defined in utils.c +// + +extern +CasaStatus +EncodeData( + IN const void *pData, + IN const int32_t dataLen, + INOUT char **ppEncodedData, + INOUT int32_t *pEncodedDataLen); + +extern +CasaStatus +DecodeData( + IN const char *pEncodedData, + IN const int32_t encodedDataLen, // Does not include NULL terminator + INOUT void **ppData, + INOUT int32_t *pDataLen); + + +//========================================================================= + +#endif // _INTERNAL_H_ diff --git a/CASA-auth-token/client/core/mechanisms/krb5/linux/Krb5Authenticate.conf b/CASA-auth-token/client/core/mechanisms/krb5/linux/Krb5Authenticate.conf new file mode 100644 index 00000000..df2ad167 --- /dev/null +++ b/CASA-auth-token/client/core/mechanisms/krb5/linux/Krb5Authenticate.conf @@ -0,0 +1,12 @@ +####################################################### +# # +# CASA Authentication Token System configuration file # +# for module: # +# # +# Krb5Authenticate # +# # +####################################################### + +LibraryName /usr/lib/CASA/authtoken/krb5mech.so + + diff --git a/CASA-auth-token/client/core/mechanisms/krb5/linux/Krb5Authenticate_lib64.conf b/CASA-auth-token/client/core/mechanisms/krb5/linux/Krb5Authenticate_lib64.conf new file mode 100644 index 00000000..c1bc0bb6 --- /dev/null +++ b/CASA-auth-token/client/core/mechanisms/krb5/linux/Krb5Authenticate_lib64.conf @@ -0,0 +1,12 @@ +####################################################### +# # +# CASA Authentication Token System configuration file # +# for module: # +# # +# Krb5Authenticate # +# # +####################################################### + +LibraryName /usr/lib64/CASA/authtoken/krb5mech.so + + diff --git a/CASA-auth-token/client/core/mechanisms/krb5/linux/Makefile.am b/CASA-auth-token/client/core/mechanisms/krb5/linux/Makefile.am new file mode 100644 index 00000000..0dc23daf --- /dev/null +++ b/CASA-auth-token/client/core/mechanisms/krb5/linux/Makefile.am @@ -0,0 +1,122 @@ +####################################################################### +# +# 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 +# +####################################################################### + +if DEBUG +TARGET_CFG = Debug +CFLAGS += -v -w +DEFINES = -DDBG +else +TARGET_CFG = Release +DEFINES = -DNDEBUG +endif + +SUBDIRS = + +DIST_SUBDIRS = + +ROOT = ../../../.. + +LIBDIR = $(ROOT)/$(LIB) + +# handle Mono secondary dependencies +export MONO_PATH := $(MONO_PATH) + +PLATFORMINDEPENDENTSOURCEDIR = .. +PLATFORMDEPENDENTSOURCEDIR = . + +MODULE_NAME = krb5mech +MODULE_EXT = so + +CFILES = get.c \ + ../interface.c \ + ../util.c \ + platform.c + +CSFILES_CSC := +INCLUDES = -I. -I.. -I../../.. -I$(ROOT)/include +RESOURCES = + +DEST_CONF_FILE_NAME = Krb5Authenticate.conf +if LIB64 +DEFINES += -D_LIB64 +SRC_CONF_FILE_NAME = Krb5Authenticate_lib64.conf +else +SRC_CONF_FILE_NAME = Krb5Authenticate.conf +endif + +CFLAGS += -Wno-format-extra-args -fno-strict-aliasing $(INCLUDES) $(DEFINES) +LIBS = -lpthread -lc -lgssapi +LDFLAGS = -Bsymbolic -shared -Wl,-soname=$(MODULE_NAME).$(MODULE_EXT) -L$(ROOT)/lib/$(TARGET_CFG) + +OBJDIR = ./$(TARGET_CFG)/$(LIB) +OBJS = $(addprefix $(OBJDIR)/, $(CFILES:%.c=%.o)) + +EXTRA_DIST = $(CFILES) *.h Krb5Authenticate.conf Krb5Authenticate_lib64.conf + +CUR_DIR := $(shell pwd) + +all: $(OBJDIR)/$(MODULE_NAME).$(MODULE_EXT) + +# +# Pattern based rules. +# +vpath %.c $(PLATFORMDEPENDENTSOURCEDIR) $(PLATFORMINDEPENDENTSOURCEDIR) +vpath %.cpp $(PLATFORMDEPENDENTSOURCEDIR) $(PLATFORMINDEPENDENTSOURCEDIR) + +$(OBJDIR)/%.o: %.c + $(CC) -c $(CFLAGS) -o $@ $< + +$(OBJDIR)/%.o: %.cpp + $(CC) -c $(CFLAGS) -o $@ $< + +$(OBJDIR)/$(MODULE_NAME).$(MODULE_EXT): $(OBJDIR) $(OBJS) + @echo [======== Linking $@ ========] + $(LINK) -o $@ $(LDFLAGS) $(OBJS) $(LIBS) + cp -f $(OBJDIR)/$(MODULE_NAME).$(MODULE_EXT) $(LIBDIR)/$(TARGET_CFG)/$(MODULE_NAME).$(MODULE_EXT) + cp -f $(SRC_CONF_FILE_NAME) $(LIBDIR)/$(TARGET_CFG)/$(DEST_CONF_FILE_NAME) + +$(OBJDIR): + [ -d $(OBJDIR) ] || mkdir -p $(OBJDIR) + [ -d $(LIBDIR) ] || mkdir -p $(LIBDIR) + [ -d $(LIBDIR)/$(TARGET_CFG) ] || mkdir -p $(LIBDIR)/$(TARGET_CFG) + +install-exec-local: $(OBJDIR)/$(MODULE_NAME).$(MODULE_EXT) + $(mkinstalldirs) $(DESTDIR)$(libdir) + $(INSTALL_PROGRAM) $(OBJDIR)/$(MODULE_NAME).$(MODULE_EXT) $(DESTDIR)$(libdir)/ + +uninstall-local: + cd $(DESTDIR)$(libdir); rm -f $(OBJDIR)/$(MODULE_NAME).$(MODULE_EXT) + rmdir $(DESTDIR)$(libdir) + +#installcheck-local: install +# $(mkinstalldirs) $(DESTDIR)$(libdir) +# $(INSTALL_PROGRAM) $(DESTDIR)$(libdir) +# cd $(DESTDIR)$(libdir); $(MONO) + +clean-local: + if [ -d $(TARGET_CFG) ]; then rm -rf $(TARGET_CFG); fi + +distclean-local: + +maintainer-clean-local: + rm -f Makefile.in + diff --git a/CASA-auth-token/client/core/mechanisms/krb5/linux/get.c b/CASA-auth-token/client/core/mechanisms/krb5/linux/get.c new file mode 100644 index 00000000..2c08d447 --- /dev/null +++ b/CASA-auth-token/client/core/mechanisms/krb5/linux/get.c @@ -0,0 +1,385 @@ +/*********************************************************************** + * + * 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 + * + ***********************************************************************/ + + +//===[ Include files ]===================================================== + +#include "internal.h" + +//===[ Type definitions ]================================================== + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + +// Mechanism OID +gss_OID g_mechOid = GSS_C_NULL_OID; + + +//++======================================================================= +void +LogGssStatuses( + IN char *operation, + IN OM_uint32 majorGssStatus, + IN OM_uint32 minorGssStatus) +// +// Arguments: +// +// Returns: +// +// Description: +// +// L2 +//=======================================================================-- +{ + OM_uint32 gssMajStat; + OM_uint32 gssMinStat; + gss_buffer_desc msg = GSS_C_EMPTY_BUFFER; + OM_uint32 gssMsgCtx; + + // Trace the messages associated with the major status + gssMsgCtx = 0; + while (1) + { + gssMajStat = gss_display_status(&gssMinStat, + majorGssStatus, + GSS_C_GSS_CODE, + g_mechOid, + &gssMsgCtx, + &msg); + if (gssMajStat != GSS_S_COMPLETE) + { + DbgTrace(0, "-LogGssStatuses- Error obtaining display status\n", 0); + break; + } + + // Trace this message + DbgTrace(0, "-LogGssStatuses- GSS-API error %s: ", operation); + DbgTrace(0, "%s\n", (char *)msg.value); + + if (msg.length != 0) + gss_release_buffer(&gssMinStat, &msg); + + if (!gssMsgCtx) + break; + } + + // Trace the messages associated with the minor status + gssMsgCtx = 0; + while (1) + { + gssMajStat = gss_display_status(&gssMinStat, + minorGssStatus, + GSS_C_MECH_CODE, + g_mechOid, + &gssMsgCtx, + &msg); + if (gssMajStat != GSS_S_COMPLETE) + { + DbgTrace(0, "-LogGssStatuses- Error obtaining display status\n", 0); + break; + } + + // Trace this message + DbgTrace(0, "-LogGssStatuses- GSS-API error %s: ", operation); + DbgTrace(0, "%s\n", (char *)msg.value); + + if (msg.length != 0) + gss_release_buffer(&gssMinStat, &msg); + + if (!gssMsgCtx) + break; + } +} + + +//++======================================================================= +CasaStatus SSCS_CALL +AuthTokenIf_GetAuthToken( + IN const void *pIfInstance, + IN const char *pContext, + IN const char *pMechInfo, + IN const char *pHostName, + IN void *pCredStoreScope, + INOUT char *pTokenBuf, + INOUT int *pTokenBufLen) +// +// Arguments: +// pIfInstance - +// Pointer to interface object. +// +// pServiceConfigIf - +// Pointer to service config object to which the client is trying to +// authenticate. +// +// pContext - +// Pointer to null terminated string containing mechanism specific +// context information. Another name for context is Authentication +// Realm. +// +// pMechInfo - +// Pointer to null terminated string containing mechanism specific +// information. This is information is provided by the server to +// aid the mechanism to generate an authentication token. For +// example, the mechanism information for a Kerberos mechanism +// may be the service principal name to which the user will be +// authenticating. +// +// pHostName - +// Pointer to null terminated string containing the name of the +// host where the ATS resides. +// +// pCredStoreScope - +// Pointer to CASA structure for scoping credential store access +// to specific users. This can only be leveraged when running in +// the context of System under Windows. +// +// pTokenBuf - +// Pointer to buffer that will receive the authentication +// token. The length of this buffer is specified by the +// pTokenBufLen parameter. Note that the the authentication +// token will be in the form of a NULL terminated string. +// +// pTokenBufLen - +// Pointer to integer that contains the length of the +// buffer pointed at by pTokenBuf. Upon return of the +// function, the integer will contain the actual length +// of the authentication token if the function successfully +// completes or the buffer length required if the function +// fails because the buffer pointed at by pUserNameBuf is +// not large enough. +// +// Returns: +// Casa Status +// +// Description: +// Get authentication token to authenticate user to specified service. +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus; + char const *pKrbServiceName = pMechInfo; + OM_uint32 gssMajStat; + OM_uint32 gssMinStat; + gss_buffer_desc gssBuffer; + gss_name_t gssServiceName; + + DbgTrace(1, "-AuthTokenIf_GetAuthToken- Start\n", 0); + + // Validate input parameters + if (pIfInstance == NULL + || pContext == NULL + || pHostName == NULL + || pTokenBufLen == NULL + || (pTokenBuf == NULL && *pTokenBufLen != 0)) + { + DbgTrace(0, "-AuthTokenIf_GetAuthToken- Invalid input parameter\n", 0); + + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_KRB5TOKEN, + CASA_STATUS_INVALID_PARAMETER); + goto exit; + } + + // Check if we need to construct the service name + if (pKrbServiceName == NULL + || strlen(pKrbServiceName) == 0) + { + // The service name will default to host/hostname + pKrbServiceName = malloc(5 /*"host/"*/ + strlen(pHostName) + 1 /*'/0'*/); + if (pKrbServiceName) + { + sprintf(pKrbServiceName, "host/%s", pHostName); + } + else + { + DbgTrace(0, "-AuthTokenIf_GetAuthToken- Memory allocation failure\n", 0); + goto exit; + } + } + + // Import the service principal name into something that + // GSS-API can understand based on its form. + gssBuffer.value = (void*) pKrbServiceName; + gssBuffer.length = strlen(pKrbServiceName) + 1; + if (strchr(pKrbServiceName, '@') != NULL) + { + // The name is of the form "servicename@hostname" + gssMajStat = gss_import_name(&gssMinStat, + &gssBuffer, + (gss_OID) GSS_C_NT_HOSTBASED_SERVICE, + &gssServiceName); + } + else + { + // The name is of the form "servicename" + gssMajStat = gss_import_name(&gssMinStat, + &gssBuffer, + (gss_OID) GSS_C_NT_USER_NAME, + &gssServiceName); + } + + // Proceed based on the result of the name import operation + if (gssMajStat == GSS_S_COMPLETE) + { + // Establish a context + gss_ctx_id_t gssContext = GSS_C_NO_CONTEXT; + gss_buffer_desc gssSendToken = {0}; + OM_uint32 gssRetFlags; + gssMajStat = gss_init_sec_context(&gssMinStat, + GSS_C_NO_CREDENTIAL, + &gssContext, + gssServiceName, + g_mechOid, + 0, // Flags + 0, + NULL, // no channel bindings + GSS_C_NO_BUFFER, // no token from peer + NULL, // ignore mech type + &gssSendToken, + &gssRetFlags, + NULL); // ignore time rec + + // Proceed based on the result of the gss_init_sec_context operation + if (gssMajStat == GSS_S_COMPLETE + && gssSendToken.length != 0) + { + char *pEncodedToken; + int encodedTokenLen; + + // The security context was initialized, now return the token to the + // caller after base64 encoding it. + retStatus = EncodeData(gssSendToken.value, + gssSendToken.length, + &pEncodedToken, + &encodedTokenLen); + if (CASA_SUCCESS(retStatus)) + { + // Verify that the caller provided a buffer that is big enough + if (encodedTokenLen > *pTokenBufLen) + { + // At least one of the supplied buffers is not big enough + DbgTrace(1, "-AuthTokenIf_GetAuthToken- Insufficient buffer space provided\n", 0); + + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_KRB5TOKEN, + CASA_STATUS_BUFFER_OVERFLOW); + } + else + { + // The buffer provided is large enough, copy the data and return the actual size. + memcpy((void*) pTokenBuf, pEncodedToken, encodedTokenLen +1); + + // Success + retStatus = CASA_STATUS_SUCCESS; + } + + // Return the actual size or the size required + *pTokenBufLen = encodedTokenLen; + + // Free the buffer containing the encoded token + free(pEncodedToken); + } + else + { + DbgTrace(1, "-AuthTokenIf_GetAuthToken- Encoding failed\n", 0); + } + } + else + { + DbgTrace(0, "-AuthTokenIf_GetAuthToken- Error initing sec context\n", 0); + LogGssStatuses("initializing context", gssMajStat, gssMinStat); + + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_KRB5TOKEN, + CASA_STATUS_UNSUCCESSFUL); + } + + // Release send token buffer if necessary + if (gssSendToken.length != 0) + gss_release_buffer(&gssMinStat, &gssSendToken); + + + // Free context if necessary + if (gssContext != GSS_C_NO_CONTEXT) + gss_delete_sec_context(&gssMinStat, &gssContext, GSS_C_NO_BUFFER); + + // Release the buffer associated with the service name + gss_release_name(&gssMinStat, &gssServiceName); + } + else + { + DbgTrace(0, "-AuthTokenIf_GetAuthToken- Error importing service name\n", 0); + LogGssStatuses("importing service name", gssMajStat, gssMinStat); + + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_KRB5TOKEN, + CASA_STATUS_OBJECT_NOT_FOUND); + } + +exit: + + // Free buffer holding the Krb Service Name if necessary + if (pKrbServiceName + && pKrbServiceName != pMechInfo) + free(pKrbServiceName); + + DbgTrace(1, "-AuthTokenIf_GetAuthToken- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +int +InitializeLibrary(void) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + int retStatus = 0; + + DbgTrace(1, "-InitializeLibrary- Start\n", 0); + + // Nothing to do at this time. + + DbgTrace(1, "-InitializeLibrary- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +//++======================================================================= +//++======================================================================= + diff --git a/CASA-auth-token/client/core/mechanisms/krb5/linux/platform.c b/CASA-auth-token/client/core/mechanisms/krb5/linux/platform.c new file mode 100644 index 00000000..869b581c --- /dev/null +++ b/CASA-auth-token/client/core/mechanisms/krb5/linux/platform.c @@ -0,0 +1,35 @@ +/*********************************************************************** + * + * 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 + * + ***********************************************************************/ + +//===[ Include files ]===================================================== + +#include "internal.h" + +//===[ Type definitions ]================================================== + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + + diff --git a/CASA-auth-token/client/core/mechanisms/krb5/linux/platform.h b/CASA-auth-token/client/core/mechanisms/krb5/linux/platform.h new file mode 100644 index 00000000..72d3c254 --- /dev/null +++ b/CASA-auth-token/client/core/mechanisms/krb5/linux/platform.h @@ -0,0 +1,90 @@ +/*********************************************************************** + * + * 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 + * + ***********************************************************************/ + +#define _GNU_SOURCE + +//===[ Include files ]===================================================== + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//===[ Type definitions ]================================================== + +#define HANDLE void* + +#ifndef CONTAINING_RECORD +#define CONTAINING_RECORD(address, type, field) ((type *)( \ + (char*)(address) - \ + (char*)(&((type *)0)->field))) +#endif + + +// +// DbgTrace macro define +// +#define DbgTrace(LEVEL, X, Y) { \ +char printBuff[256]; \ + if (LEVEL == 0 || DebugLevel >= LEVEL) \ + { \ + _snprintf(printBuff, sizeof(printBuff), X, Y); \ + fprintf(stderr, "CASA_Krb5Mech %s", printBuff); \ + } \ +} +/*#define DbgTrace(LEVEL, X, Y) { \ + if (LEVEL == 0 || DebugLevel >= LEVEL) \ + { \ + openlog("CASA_Krb5Mech", LOG_CONS | LOG_NOWAIT | LOG_ODELAY, LOG_USER); \ + syslog(LOG_USER | LOG_INFO, X, Y); \ + closelog(); \ + } \ +}*/ + + +// +// Deal with function name mapping issues +// +#define _snprintf snprintf + + +//===[ Inlines functions ]=============================================== + +//===[ Function prototypes ]=============================================== + +//===[ Global externals ]================================================== + +//===[ External prototypes ]=============================================== + + + +//========================================================================= + diff --git a/CASA-auth-token/client/core/mechanisms/krb5/util.c b/CASA-auth-token/client/core/mechanisms/krb5/util.c new file mode 100644 index 00000000..90454c7a --- /dev/null +++ b/CASA-auth-token/client/core/mechanisms/krb5/util.c @@ -0,0 +1,282 @@ +/*********************************************************************** + * + * Copyright (C) 2006 Novell, Inc. All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, Novell, Inc. + * + * To contact Novell about this file by physical or electronic mail, + * you may find current contact information at www.novell.com. + * + * Author: Juan Carlos Luciani + * + ***********************************************************************/ + +//===[ Include files ]===================================================== + +#include "internal.h" + +//===[ Type definitions ]================================================== + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + +// Debug Level +int DebugLevel = 0; + +// Tables for Base64 encoding and decoding +static const int8_t g_Base64[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +static const uint8_t g_Expand64[256] = +{ + /* ASCII table */ + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64, + 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64, + 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 +}; + + +//++======================================================================= +CasaStatus +EncodeData( + IN const void *pData, + IN const int32_t dataLen, + INOUT char **ppEncodedData, + INOUT int32_t *pEncodedDataLen) +// +// Arguments: +// +// Returns: +// +// Description: +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus; + int encodedSize; + + char *pTmp; + + DbgTrace(3, "-EncodeData- Start\n", 0); + + // Determine the encoded size and allocate a buffer to hold the encoded data + encodedSize = ((dataLen * 4 + 2) / 3) - (dataLen % 3 ) + 4; + pTmp = (char*) malloc(encodedSize); + *ppEncodedData = pTmp; + if (*ppEncodedData) + { + uint8_t *pOut, *pIn; + int i; + + // Setup pointers to move through the buffers + pIn = (uint8_t*) pData; + pOut = (uint8_t*) *ppEncodedData; + + // Perform the encoding + for (i = 0; i < dataLen - 2; i += 3) + { + *pOut++ = g_Base64[(pIn[i] >> 2) & 0x3F]; + *pOut++ = g_Base64[((pIn[i] & 0x3) << 4) | + ((int32_t)(pIn[i + 1] & 0xF0) >> 4)]; + *pOut++ = g_Base64[((pIn[i + 1] & 0xF) << 2) | + ((int32_t)(pIn[i + 2] & 0xC0) >> 6)]; + *pOut++ = g_Base64[pIn[i + 2] & 0x3F]; + } + if (i < dataLen) + { + *pOut++ = g_Base64[(pIn[i] >> 2) & 0x3F]; + if (i == (dataLen - 1)) + { + *pOut++ = g_Base64[((pIn[i] & 0x3) << 4)]; + *pOut++ = '='; + } + else + { + *pOut++ = g_Base64[((pIn[i] & 0x3) << 4) | + ((int32_t)(pIn[i + 1] & 0xF0) >> 4)]; + *pOut++ = g_Base64[((pIn[i + 1] & 0xF) << 2)]; + } + *pOut++ = '='; + } + *pOut++ = '\0'; + + // Return the encoded data length + *pEncodedDataLen = (int32_t)(pOut - (uint8_t*)*ppEncodedData); + + // Success + retStatus = CASA_STATUS_SUCCESS; + } + else + { + DbgTrace(0, "-EncodeData- Buffer allocation failure\n", 0); + + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_PWTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + + DbgTrace(3, "-EncodeData- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +CasaStatus +DecodeData( + IN const char *pEncodedData, + IN const int32_t encodedDataLen, // Does not include NULL terminator + INOUT void **ppData, + INOUT int32_t *pDataLen) +// +// Arguments: +// +// Returns: +// +// Description: +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus; + int i, j; + int decodedSize; + + DbgTrace(3, "-DecodeData- Start\n", 0); + + // Determine the decoded size + for (i = 0, j = 0; i < encodedDataLen; i++) + if (g_Expand64[((uint8_t*) pEncodedData)[i]] < 64) + j++; + decodedSize = (j * 3 + 3) / 4; + + // Allocate buffer to hold the decoded data + *ppData = malloc(decodedSize); + if (*ppData) + { + bool endReached = false; + uint8_t c0, c1, c2, c3; + uint8_t *p, *q; + + // Initialize parameters that will be used during the decode operation + c0 = c1 = c2 = c3 = 0; + p = (uint8_t*) pEncodedData; + q = (uint8_t*) *ppData; + + // Decode the data + // + // Loop through the data, piecing back information. Any newlines, and/or + // carriage returns need to be skipped. + while (j > 4) + { + while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p))) + p++; + if (64 == g_Expand64[*p]) + { + endReached = true; + break; + } + c0 = *(p++); + + while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p))) + p++; + if (64 == g_Expand64[*p]) + { + *(q++) = (uint8_t)(g_Expand64[c0] << 2); + j--; + endReached = true; + break; + } + c1 = *(p++); + + while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p))) + p++; + if (64 == g_Expand64[*p]) + { + *(q++) = (uint8_t)(g_Expand64[c0] << 2 | g_Expand64[c1] >> 4); + *(q++) = (uint8_t)(g_Expand64[c1] << 4); + j -= 2; + endReached = true; + break; + } + c2 = *(p++); + + while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p))) + p++; + if (64 == g_Expand64[*p]) + { + *(q++) = (uint8_t)(g_Expand64[c0] << 2 | g_Expand64[c1] >> 4); + *(q++) = (uint8_t)(g_Expand64[c1] << 4 | g_Expand64[c2] >> 2); + *(q++) = (uint8_t)(g_Expand64[c2] << 6); + j -= 3; + endReached = true; + break; + } + c3 = *(p++); + + *(q++) = (uint8_t)(g_Expand64[c0] << 2 | g_Expand64[c1] >> 4); + *(q++) = (uint8_t)(g_Expand64[c1] << 4 | g_Expand64[c2] >> 2); + *(q++) = (uint8_t)(g_Expand64[c2] << 6 | g_Expand64[c3]); + j -= 4; + } + if (!endReached) + { + if (j > 1) + *(q++) = (uint8_t)(g_Expand64[*p] << 2 | g_Expand64[p[1]] >> 4); + if (j > 2) + *(q++) = (uint8_t)(g_Expand64[p[1]] << 4 | g_Expand64[p[2]] >> 2); + if (j > 3) + *(q++) = (uint8_t)(g_Expand64[p[2]] << 6 | g_Expand64[p[3]]); + } + + // Return the length of the decoded data + *pDataLen = (int32_t)(q - (uint8_t*)*ppData); + + // Success + retStatus = CASA_STATUS_SUCCESS; + } + else + { + DbgTrace(0, "-DecodeData- Buffer allocation failure\n", 0); + + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_PWTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + + DbgTrace(3, "-DecodeData- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +//++======================================================================= +//++======================================================================= + diff --git a/CASA-auth-token/client/core/mechanisms/krb5/windows/Krb5Authenticate.conf b/CASA-auth-token/client/core/mechanisms/krb5/windows/Krb5Authenticate.conf new file mode 100644 index 00000000..76cbd200 --- /dev/null +++ b/CASA-auth-token/client/core/mechanisms/krb5/windows/Krb5Authenticate.conf @@ -0,0 +1,12 @@ +####################################################### +# # +# CASA Authentication Token System configuration file # +# for module: # +# # +# Krb5Authenticate # +# # +####################################################### + +LibraryName \Program Files\novell\casa\lib\krb5mech.dll + + diff --git a/CASA-auth-token/client/core/mechanisms/krb5/windows/Makefile.am b/CASA-auth-token/client/core/mechanisms/krb5/windows/Makefile.am new file mode 100644 index 00000000..d7bb146f --- /dev/null +++ b/CASA-auth-token/client/core/mechanisms/krb5/windows/Makefile.am @@ -0,0 +1,69 @@ +####################################################################### +# +# Copyright (C) 2004 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: Greg Richardson +# +####################################################################### + +SUBDIRS = + +DIST_SUBDIRS = + +EXTRA_DIST = krb5.vcproj ../*.c *.c *.h *.conf *.def + +if DEBUG +TARGET_CFG = Debug +else +TARGET_CFG = Release +endif + +PACKAGE = krb5 +TARGET_FILE = krb5mech.dll +LOG_FILE = $(PACKAGE).log + +all-am: $(TARGET_FILE) + +.PHONY: $TARGET_FILE) devenv + +devenv: + @if ! test -x "$(VSINSTALLDIR)/devenv.exe"; then echo "Error: Microsoft Visual Studio .NET is currently required to build MSI and MSM packages"; exit 1; fi + +$(TARGET_FILE): devenv + @rm -f $(LOG_FILE) $@ + @CMD='"$(VSINSTALLDIR)/devenv.exe" ../../../../auth.sln /build $(TARGET_CFG) /project $(PACKAGE) /out $(LOG_FILE)'; \ + echo $$CMD; \ + if eval $$CMD; then \ + ls -l $(TARGET_CFG)/$(TARGET_FILE); \ + else \ + grep -a "ERROR:" $(LOG_FILE); \ + fi + +package-clean clean-local: + rm -rf Release/* Release Debug/* Debug*/Release */Debug *.log *.suo + +clean: + rm -rf Release/* Release Debug/* Debug */Release */Debug *.log *.suo + +distclean-local: package-clean + rm -f Makefile + +maintainer-clean-local: + rm -f Makefile.in + + + diff --git a/CASA-auth-token/client/core/mechanisms/krb5/windows/dllsup.c b/CASA-auth-token/client/core/mechanisms/krb5/windows/dllsup.c new file mode 100644 index 00000000..1fbf8cc8 --- /dev/null +++ b/CASA-auth-token/client/core/mechanisms/krb5/windows/dllsup.c @@ -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 + * + ***********************************************************************/ + +//===[ Include files ]===================================================== + +#include "internal.h" + +//===[ External data ]===================================================== + +//===[ Manifest constants ]================================================ + +//===[ Type definitions ]================================================== + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + +UINT32 g_ulCount = 0; +UINT32 g_ulLock = 0; +HANDLE g_hModule; + + +//++======================================================================= +BOOL APIENTRY DllMain( + HANDLE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +//=======================================================================-- +{ + BOOL retStatus = TRUE; + + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + { + g_hModule = hModule; + + // Initialize the library + if (InitializeLibrary() != 0) + { + // Failed to initialize the library + OutputDebugString("CASA_KRB5_MECH -DllMain- Library initialization failed\n"); + retStatus = FALSE; + } + break; + } + + case DLL_THREAD_ATTACH: + { + g_hModule = hModule; + break; + } + + case DLL_THREAD_DETACH: + break; + + case DLL_PROCESS_DETACH: + { + /* Don't uninitialize on windows + tbd + */ + break; + } + } + + return retStatus; +} + +//++======================================================================= +// +// DllCanUnloadNow +// +// Synopsis +// +// +STDAPI +DllCanUnloadNow() +// +// Input Arguments +// +// Ouput Arguments +// +// Return Value +// S_OK The DLL can be unloaded. +// S_FALSE The DLL cannot be unloaded now. +// +// Description +// An Exported Function. +// DLLs that support the OLE Component Object Model (COM) should implement +// and export DllCanUnloadNow. +// A call to DllCanUnloadNow determines whether the DLL from which it is +// exported is still in use. A DLL is no longer in use when it is not +// managing any existing objects (the reference count on all of its objects +// is 0). +// DllCanUnloadNow returns S_FALSE if there are any existing references to +// objects that the DLL manages. +// +// Environment +// +// See Also +// +//=======================================================================-- +{ + // tbd + return ((g_ulCount == 0 && g_ulLock == 0) ? S_OK : S_FALSE); +} + +//========================================================================= +//========================================================================= + diff --git a/CASA-auth-token/client/core/mechanisms/krb5/windows/get.c b/CASA-auth-token/client/core/mechanisms/krb5/windows/get.c new file mode 100644 index 00000000..f1f1dddf --- /dev/null +++ b/CASA-auth-token/client/core/mechanisms/krb5/windows/get.c @@ -0,0 +1,300 @@ +/*********************************************************************** + * + * 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 + * + ***********************************************************************/ + + +//===[ Include files ]===================================================== + +#include "internal.h" + +//===[ Type definitions ]================================================== + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + + +//++======================================================================= +CasaStatus SSCS_CALL +AuthTokenIf_GetAuthToken( + IN const void *pIfInstance, + IN const char *pContext, + IN const char *pMechInfo, + IN const char *pHostName, + IN void *pCredStoreScope, + INOUT char *pTokenBuf, + INOUT int *pTokenBufLen) +// +// Arguments: +// pIfInstance - +// Pointer to interface object. +// +// pContext - +// Pointer to null terminated string containing mechanism specific +// context information. Another name for context is Authentication +// Realm. +// +// pMechInfo - +// Pointer to null terminated string containing mechanism specific +// information. This is information is provided by the server to +// aid the mechanism to generate an authentication token. For +// example, the mechanism information for a Kerberos mechanism +// may be the service principal name to which the user will be +// authenticating. +// +// pHostName - +// Pointer to null terminated string containing the name of the +// host where the ATS resides. +// +// pCredStoreScope - +// Pointer to CASA structure for scoping credential store access +// to specific users. This can only be leveraged when running in +// the context of System under Windows. +// +// pTokenBuf - +// Pointer to buffer that will receive the authentication +// token. The length of this buffer is specified by the +// pTokenBufLen parameter. Note that the the authentication +// token will be in the form of a NULL terminated string. +// +// pTokenBufLen - +// Pointer to integer that contains the length of the +// buffer pointed at by pTokenBuf. Upon return of the +// function, the integer will contain the actual length +// of the authentication token if the function successfully +// completes or the buffer length required if the function +// fails because the buffer pointed at by pUserNameBuf is +// not large enough. +// +// Returns: +// Casa Status +// +// Description: +// Get authentication token to authenticate user to specified service. +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus; + char *pKrbServiceName = pMechInfo; + SECURITY_STATUS secStatus; + TimeStamp expiry; + CredHandle hCredentials = {0}; + + + DbgTrace(1, "-AuthTokenIf_GetAuthToken- Start\n", 0); + + // Validate input parameters + if (pIfInstance == NULL + || pContext == NULL + || pHostName == NULL + || pTokenBufLen == NULL + || (pTokenBuf == NULL && *pTokenBufLen != 0)) + { + DbgTrace(0, "-AuthTokenIf_GetAuthToken- Invalid input parameter\n", 0); + + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_KRB5TOKEN, + CASA_STATUS_INVALID_PARAMETER); + goto exit; + } + + // Check if we need to construct the service name + if (pKrbServiceName == NULL + || strlen(pKrbServiceName) == 0) + { + // The service name will default to host/hostname + pKrbServiceName = malloc(5 /*"host/"*/ + strlen(pHostName) + 1 /*'/0'*/); + if (pKrbServiceName) + { + sprintf(pKrbServiceName, "host/%s", pHostName); + } + else + { + DbgTrace(0, "-AuthTokenIf_GetAuthToken- Memory allocation failure\n", 0); + goto exit; + } + } + + // Acquire a credential handle for the current user + secStatus = AcquireCredentialsHandle(NULL, // no principal name + "Kerberos", // package name + SECPKG_CRED_OUTBOUND, + NULL, // no logon id + NULL, // no auth data + NULL, // no get key fn + NULL, // noget key arg + &hCredentials, + &expiry); + if (secStatus == SEC_E_OK) + { + CtxtHandle hContext = {0}; + SecBuffer sendTok; + SecBufferDesc outputDesc; + ULONG retFlags; + + // We acquired the credential, now initialize a security context + // so that we can authenticate the user to the specified service. + // + // First ready an output descriptor so that we can receive the + // token buffer. + outputDesc.cBuffers = 1; + outputDesc.pBuffers = &sendTok; + outputDesc.ulVersion = SECBUFFER_VERSION; + + sendTok.BufferType = SECBUFFER_TOKEN; + sendTok.cbBuffer = 0; + sendTok.pvBuffer = NULL; + + // Initialize the security context for the specified service + secStatus = InitializeSecurityContext(&hCredentials, + NULL, + pKrbServiceName, + ISC_REQ_ALLOCATE_MEMORY, + 0, // reserved + SECURITY_NATIVE_DREP, + NULL, + 0, // reserved + &hContext, + &outputDesc, + &retFlags, + &expiry); + if (secStatus == SEC_E_OK) + { + char *pEncodedToken; + int encodedTokenLen; + + // The security context was initialized, now return it to the caller after base64 encoding it. + retStatus = EncodeData(sendTok.pvBuffer, + (const int) sendTok.cbBuffer, + &pEncodedToken, + &encodedTokenLen); + if (CASA_SUCCESS(retStatus)) + { + // Verify that the caller provided a buffer that is big enough + if (encodedTokenLen > *pTokenBufLen) + { + // The buffer is not big enough + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_KRB5TOKEN, + CASA_STATUS_BUFFER_OVERFLOW); + } + else + { + // The buffer provided is large enough, copy the data. + memcpy((void*) pTokenBuf, pEncodedToken, encodedTokenLen); + + // Success + retStatus = CASA_STATUS_SUCCESS; + } + + // Return the actual size or the size required + *pTokenBufLen = encodedTokenLen; + + // Free the buffer containing the encoded token + free(pEncodedToken); + } + + // Delete the security context + DeleteSecurityContext(&hContext); + } + else + { + DbgTrace(0, "-AuthTokenIf_GetAuthToken- Failed to initialize the security context, error = %08X\n", secStatus); + + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_KRB5TOKEN, + CASA_STATUS_UNSUCCESSFUL); + } + + // Free any buffer associated with the sendToken + if (sendTok.pvBuffer) + FreeContextBuffer(sendTok.pvBuffer); + + // Free the credential handle obtained + FreeCredentialsHandle(&hCredentials); + } + else + { + DbgTrace(1, "-AuthTokenIf_GetAuthToken- Failed to obtain the credentials handle, error = %08X\n", secStatus); + + // Set retStatus based on secStatus + if (secStatus == SEC_E_NOT_OWNER + || secStatus == SEC_E_NO_CREDENTIALS) + { + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_KRB5TOKEN, + CASA_STATUS_NO_CREDENTIALS); + } + else + { + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_KRB5TOKEN, + CASA_STATUS_UNSUCCESSFUL); + } + } + +exit: + + // Free buffer holding the Krb Service Name if necessary + if (pKrbServiceName + && pKrbServiceName != pMechInfo) + free(pKrbServiceName); + + DbgTrace(1, "-AuthTokenIf_GetAuthToken- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +int +InitializeLibrary(void) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + int retStatus = 0; + + DbgTrace(1, "-InitializeLibrary- Start\n", 0); + + // Nothing to do at this time. + + DbgTrace(1, "-InitializeLibrary- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +//++======================================================================= +//++======================================================================= + diff --git a/CASA-auth-token/client/core/mechanisms/krb5/windows/krb5.vcproj b/CASA-auth-token/client/core/mechanisms/krb5/windows/krb5.vcproj new file mode 100644 index 00000000..37a4152c --- /dev/null +++ b/CASA-auth-token/client/core/mechanisms/krb5/windows/krb5.vcproj @@ -0,0 +1,182 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CASA-auth-token/client/core/mechanisms/krb5/windows/krb5mech.def b/CASA-auth-token/client/core/mechanisms/krb5/windows/krb5mech.def new file mode 100644 index 00000000..1605afcf --- /dev/null +++ b/CASA-auth-token/client/core/mechanisms/krb5/windows/krb5mech.def @@ -0,0 +1,10 @@ +LIBRARY KRB5MECH +DESCRIPTION 'CASA Kerberos V Authentication Mechanism Library.' + + +EXPORTS +; DllRegisterServer PRIVATE +; DllUnregisterServer PRIVATE +; DllGetClassObject PRIVATE + GetAuthTokenInterface PRIVATE +; DllCanUnloadNow PRIVATE \ No newline at end of file diff --git a/CASA-auth-token/client/core/mechanisms/krb5/windows/platform.c b/CASA-auth-token/client/core/mechanisms/krb5/windows/platform.c new file mode 100644 index 00000000..869b581c --- /dev/null +++ b/CASA-auth-token/client/core/mechanisms/krb5/windows/platform.c @@ -0,0 +1,35 @@ +/*********************************************************************** + * + * 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 + * + ***********************************************************************/ + +//===[ Include files ]===================================================== + +#include "internal.h" + +//===[ Type definitions ]================================================== + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + + diff --git a/CASA-auth-token/client/core/mechanisms/krb5/windows/platform.h b/CASA-auth-token/client/core/mechanisms/krb5/windows/platform.h new file mode 100644 index 00000000..1b3f0f7f --- /dev/null +++ b/CASA-auth-token/client/core/mechanisms/krb5/windows/platform.h @@ -0,0 +1,83 @@ +/*********************************************************************** + * + * 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 + * + ***********************************************************************/ + +#ifndef _PLATFORM_H_ +#define _PLATFORM_H_ + +//===[ Include files ]===================================================== + +#include +#include +#include +#include +#include + +//===[ Type definitions ]================================================== + +#ifndef CONTAINING_RECORD +#define CONTAINING_RECORD(address, type, field) ((type *)( \ + (char*)(address) - \ + (char*)(&((type *)0)->field))) +#endif + +// +// DbgTrace macro define +// +//#define DbgTrace(LEVEL, X, Y) { \ +//char printBuff[256]; \ +// if (LEVEL == 0 || DebugLevel >= LEVEL) \ +// { \ +// _snprintf(printBuff, sizeof(printBuff), X, Y); \ +// printf("Krb5Mech %s", printBuff); \ +// } \ +//} +#define DbgTrace(LEVEL, X, Y) { \ +char formatBuff[128]; \ +char printBuff[256]; \ + if (LEVEL == 0 || DebugLevel >= LEVEL) \ + { \ + strcpy(formatBuff, "Krb5Mech "); \ + strncat(formatBuff, X, sizeof(formatBuff) - 9); \ + _snprintf(printBuff, sizeof(printBuff), formatBuff, Y); \ + OutputDebugString(printBuff); \ + } \ +} + +#define bool BOOLEAN +#define true TRUE +#define false FALSE + +//===[ Inlines functions ]=============================================== + +//===[ Function prototypes ]=============================================== + +//===[ Global externals ]================================================== + +//===[ External prototypes ]=============================================== + + +//========================================================================= + +#endif // _PLATFORM_H_ + diff --git a/CASA-auth-token/client/core/mechanisms/pwd/Makefile.am b/CASA-auth-token/client/core/mechanisms/pwd/Makefile.am new file mode 100644 index 00000000..63055631 --- /dev/null +++ b/CASA-auth-token/client/core/mechanisms/pwd/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 = $(TARGET_OS) + +DIST_SUBDIRS = linux windows + +CFILES = *.c + +EXTRA_DIST = $(CFILES) *.h + +.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/client/core/mechanisms/pwd/README b/CASA-auth-token/client/core/mechanisms/pwd/README new file mode 100644 index 00000000..002f9b8a --- /dev/null +++ b/CASA-auth-token/client/core/mechanisms/pwd/README @@ -0,0 +1,50 @@ +/*********************************************************************** + * + * 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 pwmech + * + ***********************************************************************/ + +INTRODUCTION + +pwmech is a client authentication mechanism for the support of username +and password authenticaton. The mechanism leverages the credentials stored +in the miCASA cache and does not prompt the user for credentials. + +SECURITY CONSIDERATIONS + +The tokens that pwmech generates contain the user's username and password, +this mandates that the auth_token client utilize a secure channel when +transfering them to the ATS. + + + + + + + + + + diff --git a/CASA-auth-token/client/core/mechanisms/pwd/TODO b/CASA-auth-token/client/core/mechanisms/pwd/TODO new file mode 100644 index 00000000..08437725 --- /dev/null +++ b/CASA-auth-token/client/core/mechanisms/pwd/TODO @@ -0,0 +1,13 @@ +/*********************************************************************** + * + * TODO for pwmech + * + ***********************************************************************/ + +INTRODUCTION + +This file contains a list of the items still outstanding for pwmech. + +OUTSTANDING ITEMS + +None. diff --git a/CASA-auth-token/client/core/mechanisms/pwd/get.c b/CASA-auth-token/client/core/mechanisms/pwd/get.c new file mode 100644 index 00000000..cd8a8345 --- /dev/null +++ b/CASA-auth-token/client/core/mechanisms/pwd/get.c @@ -0,0 +1,352 @@ +/*********************************************************************** + * + * 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 + * + ***********************************************************************/ + + +//===[ Include files ]===================================================== + +#include "internal.h" + +//===[ Type definitions ]================================================== + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + + +//++======================================================================= +static +CasaStatus +GetUserCredentials( + IN const char *pRealm, + IN void *pCredStoreScope, + INOUT char **ppUsername, + INOUT char **ppPassword) +// +// Arguments: +// pRealm - +// The realm to which the credentials apply. +// +// pCredStoreScope - +// Pointer to CASA structure for scoping credential store access +// to specific users. This can only be leveraged when running in +// the context of System under Windows. +// +// ppUsername - +// Pointer to variable that will receive buffer with the username. +// +// ppPassword - +// Pointer to variable that will receive buffer with the password. +// +// Returns: +// Casa Status +// +// Description: +// Get authentication credentials for the specified realm. +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_PWTOKEN, + CASA_STATUS_UNSUCCESSFUL); + char *pUsername; + char *pPassword; + int rcode = NSSCS_E_OBJECT_NOT_FOUND; + uint32_t credtype = SSCS_CRED_TYPE_BASIC_F; + SSCS_BASIC_CREDENTIAL credential = {0}; + SSCS_SECRET_ID_T secretId = {0}; + + DbgTrace(1, "-GetUserCredentials- Start\n", 0); + + // Initialize output parameters + *ppUsername = NULL; + *ppPassword = NULL; + + // Get the length of the realm string into the secret id structure + // and verify thatr it is not too long. + secretId.len = sscs_Utf8Strlen(pRealm) + 1; + if (secretId.len <= NSSCS_MAX_SECRET_ID_LEN) + { + // Set the secret id in the structure + sscs_Utf8Strcpy((char*) secretId.id, pRealm); + + // Specify that we want the common name + credential.unFlags = USERNAME_TYPE_CN_F; + + // Now try to get the credentials + rcode = miCASAGetCredential(0, + &secretId, + NULL, + &credtype, + &credential, + (SSCS_EXT_T*) pCredStoreScope); + if (rcode != NSSCS_SUCCESS) + { + // There were no credentials for the realm, now try to obtain the + // desktop credentials. + secretId.len = sscs_Utf8Strlen("Desktop") + 1; + sscs_Utf8Strcpy((char*) secretId.id, "Desktop"); + rcode = miCASAGetCredential(0, + &secretId, + NULL, + &credtype, + &credential, + (SSCS_EXT_T*) pCredStoreScope); + } + } + else + { + DbgTrace(0, "-GetUserCredentials- Realm name too long\n", 0); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_PWTOKEN, + CASA_STATUS_UNSUCCESSFUL); + } + + // Proceed based on the result of the operatiosn above + if (rcode == NSSCS_SUCCESS + && credential.username != NULL + && credential.password != NULL) + { + // Allocate a buffer to return the username + pUsername = (char*) malloc(strlen((char*) credential.username) + 1); + if (pUsername) + { + // Copy the username into the buffer that we will be returning + strcpy(pUsername, (char*) credential.username); + + // Allocate a buffer to return the password + pPassword = (char*) malloc(strlen((char*) credential.password) + 1); + if (pPassword) + { + // Copy the password into the buffer that we will be returning + strcpy(pPassword, (char*) credential.password); + + DbgTrace(1, "-GetUserCredentials- Username = %s\n", pUsername); + + // Success + retStatus = CASA_STATUS_SUCCESS; + } + else + { + DbgTrace(0, "-GetUserCredentials- Buffer allocation error\n", 0); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_PWTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + + // Free the buffer allocated for the username + free(pUsername); + } + } + else + { + DbgTrace(0, "-GetUserCredentials- Buffer allocation error\n", 0); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_PWTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + } + else + { + DbgTrace(0, "-GetUserCredentials- Failed to obtain credentials for pw authentication\n", 0); + } + + // Return the buffers to the caller if successful + if (CASA_SUCCESS(retStatus)) + { + *ppUsername = pUsername; + *ppPassword = pPassword; + } + + DbgTrace(1, "-GetUserCredentials- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +CasaStatus SSCS_CALL +AuthTokenIf_GetAuthToken( + IN const void *pIfInstance, + IN const char *pContext, + IN const char *pMechInfo, + IN const char *pHostName, + IN void *pCredStoreScope, + INOUT char *pTokenBuf, + INOUT int *pTokenBufLen) +// +// Arguments: +// pIfInstance - +// Pointer to interface object. +// +// pContext - +// Pointer to null terminated string containing mechanism specific +// context information. Another name for context is Authentication +// Realm. +// +// pMechInfo - +// Pointer to null terminated string containing mechanism specific +// information. This is information is provided by the server to +// aid the mechanism to generate an authentication token. For +// example, the mechanism information for a Kerberos mechanism +// may be the service principal name to which the user will be +// authenticating. +// +// pHostName - +// Pointer to null terminated string containing the name of the +// host where the ATS resides. +// +// pCredStoreScope - +// Pointer to CASA structure for scoping credential store access +// to specific users. This can only be leveraged when running in +// the context of System under Windows. +// +// pTokenBuf - +// Pointer to buffer that will receive the authentication +// token. The length of this buffer is specified by the +// pTokenBufLen parameter. Note that the the authentication +// token will be in the form of a NULL terminated string. +// +// pTokenBufLen - +// Pointer to integer that contains the length of the +// buffer pointed at by pTokenBuf. Upon return of the +// function, the integer will contain the actual length +// of the authentication token if the function successfully +// completes or the buffer length required if the function +// fails because the buffer pointed at by pUserNameBuf is +// not large enough. +// +// Returns: +// Casa Status +// +// Description: +// Get authentication token to authenticate user to specified service. +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus; + char *pUsername = NULL; + char *pPassword = NULL; + char *pToken; + + DbgTrace(1, "-AuthTokenIf_GetAuthToken- Start\n", 0); + + // Validate input parameters + if (pIfInstance == NULL + || pContext == NULL + || pHostName == NULL + || pTokenBufLen == NULL + || (pTokenBuf == NULL && *pTokenBufLen != 0)) + { + DbgTrace(0, "-AuthTokenIf_GetAuthToken- Invalid input parameter\n", 0); + + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_PWTOKEN, + CASA_STATUS_INVALID_PARAMETER); + goto exit; + } + + // Get the user credentials + retStatus = GetUserCredentials(pContext, + pCredStoreScope, + &pUsername, + &pPassword); + if (CASA_SUCCESS(retStatus)) + { + // Now construct the PW token with the following format: + // "username\r\n" + "password\r\n" + // + // First allocate a buffer large enough to hold the token + pToken = (char*) malloc(strlen(pUsername) + 2 + strlen(pPassword) + 2 + 1); + if (pToken) + { + char *pEncodedToken; + int encodedTokenLen; + + // Now assemble the token + sprintf(pToken, "%s\r\n%s\r\n", pUsername, pPassword); + + // The token has been assembled, now encode it. + retStatus = EncodeData(pToken, + (const int) strlen(pToken), + &pEncodedToken, + &encodedTokenLen); + if (CASA_SUCCESS(retStatus)) + { + // Verify that the caller provided a buffer that is big enough + if (encodedTokenLen > *pTokenBufLen) + { + // The buffer is not big enough + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_PWTOKEN, + CASA_STATUS_BUFFER_OVERFLOW); + } + else + { + // The buffer provided is large enough, copy the data. + memcpy((void*) pTokenBuf, pEncodedToken, encodedTokenLen); + + // Success + retStatus = CASA_STATUS_SUCCESS; + } + + // Return the actual size or the size required + *pTokenBufLen = encodedTokenLen; + + // Free the buffer containing the encoded token + free(pEncodedToken); + } + + // Free the buffer allocated for the token + free(pToken); + } + else + { + DbgTrace(0, "-AuthTokenIf_GetAuthToken- Buffer allocation error\n", 0); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_PWTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + + // Free allocated buffers + free(pUsername); + free(pPassword); + } + else + { + DbgTrace(1, "-AuthTokenIf_GetAuthToken- Failed to obtain the user credentials\n", 0); + } + +exit: + + DbgTrace(1, "-AuthTokenIf_GetAuthToken- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +//++======================================================================= +//++======================================================================= + diff --git a/CASA-auth-token/client/core/mechanisms/pwd/interface.c b/CASA-auth-token/client/core/mechanisms/pwd/interface.c new file mode 100644 index 00000000..2fbdf3f4 --- /dev/null +++ b/CASA-auth-token/client/core/mechanisms/pwd/interface.c @@ -0,0 +1,207 @@ +/*********************************************************************** + * + * 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 + * + ***********************************************************************/ + +//===[ Include files ]===================================================== + +#include "internal.h" + +//===[ Type definitions ]================================================== + +// +// Authentication Token Interface instance data +// +typedef struct _AuthTokenIfInstance +{ + int refCount; + AuthTokenIf authTokenIf; + +} AuthTokenIfInstance, *PAuthTokenIfInstance; + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + +// AuthTokenIf variables +static +int g_numAuthTokenIfObjs = 0; + + +//++======================================================================= +static +int SSCS_CALL +AuthTokenIf_AddReference( + IN const void *pIfInstance) +// +// Arguments: +// pIfInstance - +// Pointer to interface object. +// +// Returns: +// Interface reference count. +// +// Description: +// Increases interface reference count. +// +// L2 +//=======================================================================-- +{ + int refCount; + AuthTokenIfInstance *pAuthTokenIfInstance = CONTAINING_RECORD(pIfInstance, AuthTokenIfInstance, authTokenIf); + + DbgTrace(2, "-AuthTokenIf_AddReference- Start\n", 0); + + // Increment the reference count on the object + pAuthTokenIfInstance->refCount ++; + refCount = pAuthTokenIfInstance->refCount; + + DbgTrace(2, "-AuthTokenIf_AddReference- End, refCount = %08X\n", refCount); + + return refCount; +} + + +//++======================================================================= +static +void SSCS_CALL +AuthTokenIf_ReleaseReference( + IN const void *pIfInstance) +// +// Arguments: +// pIfInstance - +// Pointer to interface object. +// +// Returns: +// Nothing. +// +// Description: +// Decreases interface reference count. The interface is deallocated if +// the reference count becomes zero. +// +// L2 +//=======================================================================-- +{ + bool freeObj = false; + AuthTokenIfInstance *pAuthTokenIfInstance = CONTAINING_RECORD(pIfInstance, AuthTokenIfInstance, authTokenIf); + + DbgTrace(2, "-AuthTokenIf_ReleaseReference- Start\n", 0); + + // Decrement the reference count on the object and determine if it needs to + // be released. + pAuthTokenIfInstance->refCount --; + if (pAuthTokenIfInstance->refCount == 0) + { + // The object needs to be released, forget about it. + freeObj = true; + g_numAuthTokenIfObjs --; + } + + // Free object if necessary + if (freeObj) + free(pAuthTokenIfInstance); + + DbgTrace(2, "-AuthTokenIf_ReleaseReference- End\n", 0); +} + + +//++======================================================================= +CasaStatus SSCS_CALL +GET_AUTH_TOKEN_INTERFACE_RTN( + IN const ConfigIf *pModuleConfigIf, + INOUT AuthTokenIf **ppAuthTokenIf) +// +// Arguments: +// pModuleConfigIf - +// Pointer to configuration interface instance for the module. +// +// ppAuthTokenIf - +// Pointer to variable that will receive pointer to AuthTokenIf +// instance. +// +// Returns: +// Casa Status +// +// Description: +// Gets authentication token interface instance. +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus; + AuthTokenIfInstance *pAuthTokenIfInstance; + + + DbgTrace(1, "-GetAuthTokenInterface- Start\n", 0); + + // Validate input parameters + if (pModuleConfigIf == NULL + || ppAuthTokenIf == NULL) + { + DbgTrace(0, "-GetAuthTokenInterface- Invalid input parameter\n", 0); + + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_PWTOKEN, + CASA_STATUS_INVALID_PARAMETER); + goto exit; + } + + // Allocate space for the interface instance + pAuthTokenIfInstance = malloc(sizeof(*pAuthTokenIfInstance)); + if (pAuthTokenIfInstance) + { + // Initialize the interface instance data + pAuthTokenIfInstance->refCount = 1; + pAuthTokenIfInstance->authTokenIf.addReference = AuthTokenIf_AddReference; + pAuthTokenIfInstance->authTokenIf.releaseReference = AuthTokenIf_ReleaseReference; + pAuthTokenIfInstance->authTokenIf.getAuthToken = AuthTokenIf_GetAuthToken; + + // Keep track of this object + g_numAuthTokenIfObjs ++; + + // Return the interface to the caller + *ppAuthTokenIf = &pAuthTokenIfInstance->authTokenIf; + + // Success + retStatus = CASA_STATUS_SUCCESS; + } + else + { + DbgTrace(0, "-GetAuthTokenInterface- Buffer allocation failure\n", 0); + + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_PWTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + +exit: + + DbgTrace(1, "-GetAuthTokenInterface- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +//++======================================================================= +//++======================================================================= + diff --git a/CASA-auth-token/client/core/mechanisms/pwd/internal.h b/CASA-auth-token/client/core/mechanisms/pwd/internal.h new file mode 100644 index 00000000..b2a221d9 --- /dev/null +++ b/CASA-auth-token/client/core/mechanisms/pwd/internal.h @@ -0,0 +1,90 @@ +/*********************************************************************** + * + * 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 + * + ***********************************************************************/ + +#ifndef _INTERNAL_H_ +#define _INTERNAL_H_ + +//===[ Include files ]===================================================== + +#include "platform.h" +#include +#include +#include +#include +#include "config_if.h" +#include "mech_if.h" + +//===[ Type definitions ]================================================== + +//===[ Inlines functions ]=============================================== + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + +//===[ Global externals ]================================================== + +extern int DebugLevel; + +//===[ External prototypes ]=============================================== + +// +// Defined in get.c +// + +extern +CasaStatus SSCS_CALL +AuthTokenIf_GetAuthToken( + IN const void *pIfInstance, + IN const char *pContext, + IN const char *pMechInfo, + IN const char *pHostName, + IN void *pCredStoreScope, + INOUT char *pTokenBuf, + INOUT int *pTokenBufLen); + +// +// Defined in utils.c +// + +extern +CasaStatus +EncodeData( + IN const void *pData, + IN const int32_t dataLen, + INOUT char **ppEncodedData, + INOUT int32_t *pEncodedDataLen); + +extern +CasaStatus +DecodeData( + IN const char *pEncodedData, + IN const int32_t encodedDataLen, // Does not include NULL terminator + INOUT void **ppData, + INOUT int32_t *pDataLen); + +//========================================================================= + +#endif // _INTERNAL_H_ + diff --git a/CASA-auth-token/client/core/mechanisms/pwd/linux/Makefile.am b/CASA-auth-token/client/core/mechanisms/pwd/linux/Makefile.am new file mode 100644 index 00000000..372511f1 --- /dev/null +++ b/CASA-auth-token/client/core/mechanisms/pwd/linux/Makefile.am @@ -0,0 +1,122 @@ +####################################################################### +# +# 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 +# +####################################################################### + +if DEBUG +TARGET_CFG = Debug +CFLAGS += -v -w +DEFINES = -DDBG +else +TARGET_CFG = Release +DEFINES = -DNDEBUG +endif + +SUBDIRS = + +DIST_SUBDIRS = + +ROOT = ../../../.. + +LIBDIR = $(ROOT)/$(LIB) + +# handle Mono secondary dependencies +export MONO_PATH := $(MONO_PATH) + +PLATFORMINDEPENDENTSOURCEDIR = .. +PLATFORMDEPENDENTSOURCEDIR = . + +MODULE_NAME = pwmech +MODULE_EXT = so + +CFILES = ../get.c \ + ../interface.c \ + ../util.c \ + platform.c + +CSFILES_CSC := +INCLUDES = -I. -I.. -I../../.. -I$(ROOT)/include +RESOURCES = + +DEST_CONF_FILE_NAME = PwdAuthenticate.conf +if LIB64 +DEFINES += -D_LIB64 +SRC_CONF_FILE_NAME = PwdAuthenticate_lib64.conf +else +SRC_CONF_FILE_NAME = PwdAuthenticate.conf +endif + +CFLAGS += -Wno-format-extra-args -fno-strict-aliasing $(INCLUDES) $(DEFINES) +LIBS = -lpthread -lmicasa +LDFLAGS = -Bsymbolic -shared -Wl,-soname=$(MODULE_NAME).$(MODULE_EXT) -L$(ROOT)/lib/$(TARGET_CFG) + +OBJDIR = ./$(TARGET_CFG)/$(LIB) +OBJS = $(addprefix $(OBJDIR)/, $(CFILES:%.c=%.o)) + +EXTRA_DIST = $(CFILES) *.h PwdAuthenticate.conf PwdAuthenticate_lib64.conf + +CUR_DIR := $(shell pwd) + +all: $(OBJDIR)/$(MODULE_NAME).$(MODULE_EXT) + +# +# Pattern based rules. +# +vpath %.c $(PLATFORMDEPENDENTSOURCEDIR) $(PLATFORMINDEPENDENTSOURCEDIR) +vpath %.cpp $(PLATFORMDEPENDENTSOURCEDIR) $(PLATFORMINDEPENDENTSOURCEDIR) + +$(OBJDIR)/%.o: %.c + $(CC) -c $(CFLAGS) -o $@ $< + +$(OBJDIR)/%.o: %.cpp + $(CC) -c $(CFLAGS) -o $@ $< + +$(OBJDIR)/$(MODULE_NAME).$(MODULE_EXT): $(OBJDIR) $(OBJS) + @echo [======== Linking $@ ========] + $(LINK) -o $@ $(LDFLAGS) $(OBJS) $(LIBS) + cp -f $(OBJDIR)/$(MODULE_NAME).$(MODULE_EXT) $(LIBDIR)/$(TARGET_CFG)/$(MODULE_NAME).$(MODULE_EXT) + cp -f $(SRC_CONF_FILE_NAME) $(LIBDIR)/$(TARGET_CFG)/$(DEST_CONF_FILE_NAME) + +$(OBJDIR): + [ -d $(OBJDIR) ] || mkdir -p $(OBJDIR) + [ -d $(LIBDIR) ] || mkdir -p $(LIBDIR) + [ -d $(LIBDIR)/$(TARGET_CFG) ] || mkdir -p $(LIBDIR)/$(TARGET_CFG) + +install-exec-local: $(OBJDIR)/$(MODULE_NAME).$(MODULE_EXT) + $(mkinstalldirs) $(DESTDIR)$(libdir) + $(INSTALL_PROGRAM) $(OBJDIR)/$(MODULE_NAME).$(MODULE_EXT) $(DESTDIR)$(libdir)/ + +uninstall-local: + cd $(DESTDIR)$(libdir); rm -f $(OBJDIR)/$(MODULE_NAME).$(MODULE_EXT) + rmdir $(DESTDIR)$(libdir) + +#installcheck-local: install +# $(mkinstalldirs) $(DESTDIR)$(libdir) +# $(INSTALL_PROGRAM) $(DESTDIR)$(libdir) +# cd $(DESTDIR)$(libdir); $(MONO) + +clean-local: + if [ -d $(TARGET_CFG) ]; then rm -rf $(TARGET_CFG); fi + +distclean-local: + +maintainer-clean-local: + rm -f Makefile.in + diff --git a/CASA-auth-token/client/core/mechanisms/pwd/linux/PwdAuthenticate.conf b/CASA-auth-token/client/core/mechanisms/pwd/linux/PwdAuthenticate.conf new file mode 100644 index 00000000..f991c1a8 --- /dev/null +++ b/CASA-auth-token/client/core/mechanisms/pwd/linux/PwdAuthenticate.conf @@ -0,0 +1,12 @@ +####################################################### +# # +# CASA Authentication Token System configuration file # +# for module: # +# # +# PwdAuthenticate # +# # +####################################################### + +LibraryName /usr/lib/CASA/authtoken/pwmech.so + + diff --git a/CASA-auth-token/client/core/mechanisms/pwd/linux/PwdAuthenticate_lib64.conf b/CASA-auth-token/client/core/mechanisms/pwd/linux/PwdAuthenticate_lib64.conf new file mode 100644 index 00000000..f0435d9c --- /dev/null +++ b/CASA-auth-token/client/core/mechanisms/pwd/linux/PwdAuthenticate_lib64.conf @@ -0,0 +1,12 @@ +####################################################### +# # +# CASA Authentication Token System configuration file # +# for module: # +# # +# PwdAuthenticate # +# # +####################################################### + +LibraryName /usr/lib64/CASA/authtoken/pwmech.so + + diff --git a/CASA-auth-token/client/core/mechanisms/pwd/linux/platform.c b/CASA-auth-token/client/core/mechanisms/pwd/linux/platform.c new file mode 100644 index 00000000..869b581c --- /dev/null +++ b/CASA-auth-token/client/core/mechanisms/pwd/linux/platform.c @@ -0,0 +1,35 @@ +/*********************************************************************** + * + * 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 + * + ***********************************************************************/ + +//===[ Include files ]===================================================== + +#include "internal.h" + +//===[ Type definitions ]================================================== + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + + diff --git a/CASA-auth-token/client/core/mechanisms/pwd/linux/platform.h b/CASA-auth-token/client/core/mechanisms/pwd/linux/platform.h new file mode 100644 index 00000000..f2f6c09e --- /dev/null +++ b/CASA-auth-token/client/core/mechanisms/pwd/linux/platform.h @@ -0,0 +1,88 @@ +/*********************************************************************** + * + * 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 + * + ***********************************************************************/ + +#define _GNU_SOURCE + +//===[ Include files ]===================================================== + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//===[ Type definitions ]================================================== + +#define HANDLE void* + +#ifndef CONTAINING_RECORD +#define CONTAINING_RECORD(address, type, field) ((type *)( \ + (char*)(address) - \ + (char*)(&((type *)0)->field))) +#endif + + +// +// DbgTrace macro define +// +#define DbgTrace(LEVEL, X, Y) { \ +char printBuff[256]; \ + if (LEVEL == 0 || DebugLevel >= LEVEL) \ + { \ + _snprintf(printBuff, sizeof(printBuff), X, Y); \ + fprintf(stderr, "CASA_PwMech %s", printBuff); \ + } \ +} +/*#define DbgTrace(LEVEL, X, Y) { \ + if (LEVEL == 0 || DebugLevel >= LEVEL) \ + { \ + openlog("CASA_PwMech", LOG_CONS | LOG_NOWAIT | LOG_ODELAY, LOG_USER); \ + syslog(LOG_USER | LOG_INFO, X, Y); \ + closelog(); \ + } \ +}*/ + + +// +// Deal with function name mapping issues +// +#define _snprintf snprintf + + +//===[ Inlines functions ]=============================================== + +//===[ Function prototypes ]=============================================== + +//===[ Global externals ]================================================== + +//===[ External prototypes ]=============================================== + + + +//========================================================================= + diff --git a/CASA-auth-token/client/core/mechanisms/pwd/util.c b/CASA-auth-token/client/core/mechanisms/pwd/util.c new file mode 100644 index 00000000..90454c7a --- /dev/null +++ b/CASA-auth-token/client/core/mechanisms/pwd/util.c @@ -0,0 +1,282 @@ +/*********************************************************************** + * + * Copyright (C) 2006 Novell, Inc. All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, Novell, Inc. + * + * To contact Novell about this file by physical or electronic mail, + * you may find current contact information at www.novell.com. + * + * Author: Juan Carlos Luciani + * + ***********************************************************************/ + +//===[ Include files ]===================================================== + +#include "internal.h" + +//===[ Type definitions ]================================================== + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + +// Debug Level +int DebugLevel = 0; + +// Tables for Base64 encoding and decoding +static const int8_t g_Base64[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +static const uint8_t g_Expand64[256] = +{ + /* ASCII table */ + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64, + 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64, + 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 +}; + + +//++======================================================================= +CasaStatus +EncodeData( + IN const void *pData, + IN const int32_t dataLen, + INOUT char **ppEncodedData, + INOUT int32_t *pEncodedDataLen) +// +// Arguments: +// +// Returns: +// +// Description: +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus; + int encodedSize; + + char *pTmp; + + DbgTrace(3, "-EncodeData- Start\n", 0); + + // Determine the encoded size and allocate a buffer to hold the encoded data + encodedSize = ((dataLen * 4 + 2) / 3) - (dataLen % 3 ) + 4; + pTmp = (char*) malloc(encodedSize); + *ppEncodedData = pTmp; + if (*ppEncodedData) + { + uint8_t *pOut, *pIn; + int i; + + // Setup pointers to move through the buffers + pIn = (uint8_t*) pData; + pOut = (uint8_t*) *ppEncodedData; + + // Perform the encoding + for (i = 0; i < dataLen - 2; i += 3) + { + *pOut++ = g_Base64[(pIn[i] >> 2) & 0x3F]; + *pOut++ = g_Base64[((pIn[i] & 0x3) << 4) | + ((int32_t)(pIn[i + 1] & 0xF0) >> 4)]; + *pOut++ = g_Base64[((pIn[i + 1] & 0xF) << 2) | + ((int32_t)(pIn[i + 2] & 0xC0) >> 6)]; + *pOut++ = g_Base64[pIn[i + 2] & 0x3F]; + } + if (i < dataLen) + { + *pOut++ = g_Base64[(pIn[i] >> 2) & 0x3F]; + if (i == (dataLen - 1)) + { + *pOut++ = g_Base64[((pIn[i] & 0x3) << 4)]; + *pOut++ = '='; + } + else + { + *pOut++ = g_Base64[((pIn[i] & 0x3) << 4) | + ((int32_t)(pIn[i + 1] & 0xF0) >> 4)]; + *pOut++ = g_Base64[((pIn[i + 1] & 0xF) << 2)]; + } + *pOut++ = '='; + } + *pOut++ = '\0'; + + // Return the encoded data length + *pEncodedDataLen = (int32_t)(pOut - (uint8_t*)*ppEncodedData); + + // Success + retStatus = CASA_STATUS_SUCCESS; + } + else + { + DbgTrace(0, "-EncodeData- Buffer allocation failure\n", 0); + + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_PWTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + + DbgTrace(3, "-EncodeData- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +CasaStatus +DecodeData( + IN const char *pEncodedData, + IN const int32_t encodedDataLen, // Does not include NULL terminator + INOUT void **ppData, + INOUT int32_t *pDataLen) +// +// Arguments: +// +// Returns: +// +// Description: +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus; + int i, j; + int decodedSize; + + DbgTrace(3, "-DecodeData- Start\n", 0); + + // Determine the decoded size + for (i = 0, j = 0; i < encodedDataLen; i++) + if (g_Expand64[((uint8_t*) pEncodedData)[i]] < 64) + j++; + decodedSize = (j * 3 + 3) / 4; + + // Allocate buffer to hold the decoded data + *ppData = malloc(decodedSize); + if (*ppData) + { + bool endReached = false; + uint8_t c0, c1, c2, c3; + uint8_t *p, *q; + + // Initialize parameters that will be used during the decode operation + c0 = c1 = c2 = c3 = 0; + p = (uint8_t*) pEncodedData; + q = (uint8_t*) *ppData; + + // Decode the data + // + // Loop through the data, piecing back information. Any newlines, and/or + // carriage returns need to be skipped. + while (j > 4) + { + while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p))) + p++; + if (64 == g_Expand64[*p]) + { + endReached = true; + break; + } + c0 = *(p++); + + while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p))) + p++; + if (64 == g_Expand64[*p]) + { + *(q++) = (uint8_t)(g_Expand64[c0] << 2); + j--; + endReached = true; + break; + } + c1 = *(p++); + + while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p))) + p++; + if (64 == g_Expand64[*p]) + { + *(q++) = (uint8_t)(g_Expand64[c0] << 2 | g_Expand64[c1] >> 4); + *(q++) = (uint8_t)(g_Expand64[c1] << 4); + j -= 2; + endReached = true; + break; + } + c2 = *(p++); + + while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p))) + p++; + if (64 == g_Expand64[*p]) + { + *(q++) = (uint8_t)(g_Expand64[c0] << 2 | g_Expand64[c1] >> 4); + *(q++) = (uint8_t)(g_Expand64[c1] << 4 | g_Expand64[c2] >> 2); + *(q++) = (uint8_t)(g_Expand64[c2] << 6); + j -= 3; + endReached = true; + break; + } + c3 = *(p++); + + *(q++) = (uint8_t)(g_Expand64[c0] << 2 | g_Expand64[c1] >> 4); + *(q++) = (uint8_t)(g_Expand64[c1] << 4 | g_Expand64[c2] >> 2); + *(q++) = (uint8_t)(g_Expand64[c2] << 6 | g_Expand64[c3]); + j -= 4; + } + if (!endReached) + { + if (j > 1) + *(q++) = (uint8_t)(g_Expand64[*p] << 2 | g_Expand64[p[1]] >> 4); + if (j > 2) + *(q++) = (uint8_t)(g_Expand64[p[1]] << 4 | g_Expand64[p[2]] >> 2); + if (j > 3) + *(q++) = (uint8_t)(g_Expand64[p[2]] << 6 | g_Expand64[p[3]]); + } + + // Return the length of the decoded data + *pDataLen = (int32_t)(q - (uint8_t*)*ppData); + + // Success + retStatus = CASA_STATUS_SUCCESS; + } + else + { + DbgTrace(0, "-DecodeData- Buffer allocation failure\n", 0); + + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_PWTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + + DbgTrace(3, "-DecodeData- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +//++======================================================================= +//++======================================================================= + diff --git a/CASA-auth-token/client/core/mechanisms/pwd/windows/Makefile.am b/CASA-auth-token/client/core/mechanisms/pwd/windows/Makefile.am new file mode 100644 index 00000000..fcf613f3 --- /dev/null +++ b/CASA-auth-token/client/core/mechanisms/pwd/windows/Makefile.am @@ -0,0 +1,69 @@ +####################################################################### +# +# Copyright (C) 2004 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: Greg Richardson +# +####################################################################### + +SUBDIRS = + +DIST_SUBDIRS = + +EXTRA_DIST = pwd.vcproj ../*.c *.c *.h *.conf *.def + +if DEBUG +TARGET_CFG = Debug +else +TARGET_CFG = Release +endif + +PACKAGE = pwd +TARGET_FILE = pwmech.dll +LOG_FILE = $(PACKAGE).log + +all-am: $(TARGET_FILE) + +.PHONY: $TARGET_FILE) devenv + +devenv: + @if ! test -x "$(VSINSTALLDIR)/devenv.exe"; then echo "Error: Microsoft Visual Studio .NET is currently required to build MSI and MSM packages"; exit 1; fi + +$(TARGET_FILE): devenv + @rm -f $(LOG_FILE) $@ + @CMD='"$(VSINSTALLDIR)/devenv.exe" ../../../../auth.sln /build $(TARGET_CFG) /project $(PACKAGE) /out $(LOG_FILE)'; \ + echo $$CMD; \ + if eval $$CMD; then \ + ls -l $(TARGET_CFG)/$(TARGET_FILE); \ + else \ + grep -a "ERROR:" $(LOG_FILE); \ + fi + +package-clean clean-local: + rm -rf Release/* Release Debug/* Debug*/Release */Debug *.log *.suo + +clean: + rm -rf Release/* Release Debug/* Debug */Release */Debug *.log *.suo + +distclean-local: package-clean + rm -f Makefile + +maintainer-clean-local: + rm -f Makefile.in + + + diff --git a/CASA-auth-token/client/core/mechanisms/pwd/windows/PwdAuthenticate.conf b/CASA-auth-token/client/core/mechanisms/pwd/windows/PwdAuthenticate.conf new file mode 100644 index 00000000..dd6c1eb5 --- /dev/null +++ b/CASA-auth-token/client/core/mechanisms/pwd/windows/PwdAuthenticate.conf @@ -0,0 +1,12 @@ +####################################################### +# # +# CASA Authentication Token System configuration file # +# for module: # +# # +# PwdAuthenticate # +# # +####################################################### + +LibraryName \Program Files\novell\casa\lib\pwmech.dll + + diff --git a/CASA-auth-token/client/core/mechanisms/pwd/windows/dllsup.c b/CASA-auth-token/client/core/mechanisms/pwd/windows/dllsup.c new file mode 100644 index 00000000..2aff8d4e --- /dev/null +++ b/CASA-auth-token/client/core/mechanisms/pwd/windows/dllsup.c @@ -0,0 +1,126 @@ +/*********************************************************************** + * + * 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 + * + ***********************************************************************/ + +//===[ Include files ]===================================================== + +#include "internal.h" + +//===[ External data ]===================================================== + +//===[ Manifest constants ]================================================ + +//===[ Type definitions ]================================================== + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + +UINT32 g_ulCount = 0; +UINT32 g_ulLock = 0; +HANDLE g_hModule; + + +//++======================================================================= +BOOL APIENTRY DllMain( + HANDLE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +//=======================================================================-- +{ + BOOL retStatus = TRUE; + + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + { + g_hModule = hModule; + + // Nothing else to do at this time + break; + } + + case DLL_THREAD_ATTACH: + { + g_hModule = hModule; + break; + } + + case DLL_THREAD_DETACH: + break; + + case DLL_PROCESS_DETACH: + { + /* Don't uninitialize on windows + tbd + */ + break; + } + } + + return retStatus; +} + +//++======================================================================= +// +// DllCanUnloadNow +// +// Synopsis +// +// +STDAPI +DllCanUnloadNow() +// +// Input Arguments +// +// Ouput Arguments +// +// Return Value +// S_OK The DLL can be unloaded. +// S_FALSE The DLL cannot be unloaded now. +// +// Description +// An Exported Function. +// DLLs that support the OLE Component Object Model (COM) should implement +// and export DllCanUnloadNow. +// A call to DllCanUnloadNow determines whether the DLL from which it is +// exported is still in use. A DLL is no longer in use when it is not +// managing any existing objects (the reference count on all of its objects +// is 0). +// DllCanUnloadNow returns S_FALSE if there are any existing references to +// objects that the DLL manages. +// +// Environment +// +// See Also +// +//=======================================================================-- +{ + // tbd + return ((g_ulCount == 0 && g_ulLock == 0) ? S_OK : S_FALSE); +} + +//========================================================================= +//========================================================================= + diff --git a/CASA-auth-token/client/core/mechanisms/pwd/windows/platform.c b/CASA-auth-token/client/core/mechanisms/pwd/windows/platform.c new file mode 100644 index 00000000..869b581c --- /dev/null +++ b/CASA-auth-token/client/core/mechanisms/pwd/windows/platform.c @@ -0,0 +1,35 @@ +/*********************************************************************** + * + * 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 + * + ***********************************************************************/ + +//===[ Include files ]===================================================== + +#include "internal.h" + +//===[ Type definitions ]================================================== + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + + diff --git a/CASA-auth-token/client/core/mechanisms/pwd/windows/platform.h b/CASA-auth-token/client/core/mechanisms/pwd/windows/platform.h new file mode 100644 index 00000000..b447c1a9 --- /dev/null +++ b/CASA-auth-token/client/core/mechanisms/pwd/windows/platform.h @@ -0,0 +1,81 @@ +/*********************************************************************** + * + * 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 + * + ***********************************************************************/ + +#ifndef _PLATFORM_H_ +#define _PLATFORM_H_ + +//===[ Include files ]===================================================== + +#include +#include +#include + +//===[ Type definitions ]================================================== + +#ifndef CONTAINING_RECORD +#define CONTAINING_RECORD(address, type, field) ((type *)( \ + (char*)(address) - \ + (char*)(&((type *)0)->field))) +#endif + +// +// DbgTrace macro define +// +//#define DbgTrace(LEVEL, X, Y) { \ +//char printBuff[256]; \ +// if (LEVEL == 0 || DebugLevel >= LEVEL) \ +// { \ +// _snprintf(printBuff, sizeof(printBuff), X, Y); \ +// printf("PwdMech %s", printBuff); \ +// } \ +//} +#define DbgTrace(LEVEL, X, Y) { \ +char formatBuff[128]; \ +char printBuff[256]; \ + if (LEVEL == 0 || DebugLevel >= LEVEL) \ + { \ + strcpy(formatBuff, "CASA_PwdMech "); \ + strncat(formatBuff, X, sizeof(formatBuff) - 8); \ + _snprintf(printBuff, sizeof(printBuff), formatBuff, Y); \ + OutputDebugString(printBuff); \ + } \ +} + +#define bool BOOLEAN +#define true TRUE +#define false FALSE + +//===[ Inlines functions ]=============================================== + +//===[ Function prototypes ]=============================================== + +//===[ Global externals ]================================================== + +//===[ External prototypes ]=============================================== + + +//========================================================================= + +#endif // _PLATFORM_H_ + diff --git a/CASA-auth-token/client/core/mechanisms/pwd/windows/pwd.vcproj b/CASA-auth-token/client/core/mechanisms/pwd/windows/pwd.vcproj new file mode 100644 index 00000000..6502266e --- /dev/null +++ b/CASA-auth-token/client/core/mechanisms/pwd/windows/pwd.vcproj @@ -0,0 +1,182 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CASA-auth-token/client/core/mechanisms/pwd/windows/pwmech.def b/CASA-auth-token/client/core/mechanisms/pwd/windows/pwmech.def new file mode 100644 index 00000000..0557e401 --- /dev/null +++ b/CASA-auth-token/client/core/mechanisms/pwd/windows/pwmech.def @@ -0,0 +1,10 @@ +LIBRARY PWMECH +DESCRIPTION 'CASA PW Authentication Mechanism Library.' + + +EXPORTS +; DllRegisterServer PRIVATE +; DllUnregisterServer PRIVATE +; DllGetClassObject PRIVATE + GetAuthTokenInterface PRIVATE +; DllCanUnloadNow PRIVATE \ No newline at end of file diff --git a/CASA-auth-token/client/core/test/CASA_Auth.cpp b/CASA-auth-token/client/core/test/CASA_Auth.cpp new file mode 100644 index 00000000..e78e3e4c --- /dev/null +++ b/CASA-auth-token/client/core/test/CASA_Auth.cpp @@ -0,0 +1,382 @@ +/*********************************************************************** + * + * 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 + * + ***********************************************************************/ + +#include "platform.h" + +// Externals +extern +char *pServerAddress; + +extern +int serverPort; + +extern +bool execHttpTest; + +extern +char serviceName[]; + +extern +char *pServiceName; + + +/*********************************************************************** + * + * EncodeData() + * + ***********************************************************************/ +int +EncodeData( + IN const void *pData, + IN const int32_t dataLen, + INOUT char **ppEncodedData, + INOUT int32_t *pEncodedDataLen) +{ + int8_t base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + int retStatus; + int encodedSize; + + char *pTmp; + + // Determine the encoded size and allocate a buffer to hold the encoded data + encodedSize = ((dataLen * 4 + 2) / 3) - (dataLen % 3 ) + 4; + pTmp = (char*) malloc(encodedSize); + *ppEncodedData = pTmp; + if (*ppEncodedData) + { + uint8_t *pOut, *pIn; + int i; + + // Setup pointers to move through the buffers + pIn = (uint8_t*) pData; + pOut = (uint8_t*) *ppEncodedData; + + // Perform the encoding + for (i = 0; i < dataLen - 2; i += 3) + { + *pOut++ = base64[(pIn[i] >> 2) & 0x3F]; + *pOut++ = base64[((pIn[i] & 0x3) << 4) | + ((int32_t)(pIn[i + 1] & 0xF0) >> 4)]; + *pOut++ = base64[((pIn[i + 1] & 0xF) << 2) | + ((int32_t)(pIn[i + 2] & 0xC0) >> 6)]; + *pOut++ = base64[pIn[i + 2] & 0x3F]; + } + if (i < dataLen) + { + *pOut++ = base64[(pIn[i] >> 2) & 0x3F]; + if (i == (dataLen - 1)) + { + *pOut++ = base64[((pIn[i] & 0x3) << 4)]; + *pOut++ = '='; + } + else + { + *pOut++ = base64[((pIn[i] & 0x3) << 4) | + ((int32_t)(pIn[i + 1] & 0xF0) >> 4)]; + *pOut++ = base64[((pIn[i + 1] & 0xF) << 2)]; + } + *pOut++ = '='; + } + *pOut++ = '\0'; + + // Return the encoded data length + *pEncodedDataLen = (int32_t)(pOut - (uint8_t*)*ppEncodedData); + + // Success + retStatus = 0; + } + else + { + printf("-EncodeData- Buffer allocation failure\n"); + retStatus = -1; + } + + return retStatus; +} + + +/*********************************************************************** + * + * NonHttpTest() + * + ***********************************************************************/ +void NonHttpTest(void) +{ + CasaStatus retStatus; + char authToken[8192]; + int authTokenLen = sizeof(authToken); + + // Obtain an authentication token for the targeted service + retStatus = ObtainAuthToken(pServiceName, pServerAddress, authToken, &authTokenLen); + if (!CASA_SUCCESS(retStatus)) + { + printf("-NonHttpTest- ObtainAuthToken failed with status %d\n", retStatus); + } + else + { + SOCKET sock; + struct sockaddr_in localAddr = {0}; + struct sockaddr_in remoteAddr = {0}; + struct linger linger_opt = {1, 15}; + struct hostent *pLookupResult; + + printf("-NonHttpTest- ObtainAuthToken succedded, tokenlen = %d\n", authTokenLen); + + // Send the token to the server + // + // Open socket + sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (sock != INVALID_SOCKET) + { + // Setup the local address structure + localAddr.sin_family = AF_INET; + localAddr.sin_addr.s_addr = htonl(INADDR_ANY); + + // Bind socket + if (!bind(sock, (const struct sockaddr*) &localAddr, sizeof(struct sockaddr_in))) + { + // Resolve the server address + pLookupResult = gethostbyname(pServerAddress); + if (pLookupResult) + { + // Validate the address type returned + if (pLookupResult->h_addrtype == AF_INET) + { + int numAddressesFound = 0; + + // Determine how many addresses where returned + while (pLookupResult->h_addr_list[numAddressesFound] != NULL) + { + //printf("ServerAddress = %08X\n", *((int*) pLookupResult->h_addr_list[numAddressesFound])); + numAddressesFound ++; + } + //printf("Found %d addresses\n", numAddressesFound); + + // Setup the remote address structure with the lookup results + remoteAddr.sin_family = AF_INET; + remoteAddr.sin_port = serverPort; + remoteAddr.sin_addr.s_addr = *((int*) pLookupResult->h_addr_list[0]); // Short-cut + //printf("ServerAddress = %08X\n", remoteAddr.sin_addr.s_addr); + + // Perform connect operation + if (connect(sock, + (struct sockaddr*) &remoteAddr, + sizeof(struct sockaddr_in)) == SOCKET_ERROR) + { + printf("-NonHttpTest- Connection creation failed, error = %d\n", errno); + } + else + { + // Now the connection is setup, send the credentials to the server as one line. + // using our cheesy protocol followed by a hello string. + // + // Send the token to the server (including NULL terminator) + send(sock, authToken, (int) strlen(authToken) + 1, 0); + + // Send new line + send(sock, "\n", 1, 0); + + // Send "hello" + //send(sock, helloString, strlen(helloString) + 1, MSG_NOSIGNAL); + + // Send new line + //send(sock, "\n", 1, 0); + + // Shutdown the connection + shutdown(sock, 0); + } + } + else + { + printf("-NonHttpTest- Unsupported address type returned %08X\n", pLookupResult->h_addrtype); + } + } + else + { + printf("-NonHttpTest- Lookup for %s failed\n", pServerAddress); + } + } + else + { + printf("-NonHttpTest- Unable to bind socket, error = %d", errno); + } + + // Close the socket + setsockopt(sock, SOL_SOCKET, SO_LINGER, (const char*) &linger_opt, sizeof(linger_opt)); + closesocket(sock); + } + else + { + printf("-NonHttpTest- Unable to open socket, error = %d\n", errno); + } + } +} + + +/*********************************************************************** + * + * HttpTest() + * + ***********************************************************************/ +void HttpTest(void) +{ + CasaStatus retStatus; + char authToken[4096]; + int authTokenLen = sizeof(authToken); + + // Obtain an authentication token for the targeted service + retStatus = ObtainAuthToken(pServiceName, pServerAddress, authToken, &authTokenLen); + if (!CASA_SUCCESS(retStatus)) + { + printf("-HttpTest- ObtainAuthToken failed with status %d\n", retStatus); + } + else + { + SOCKET sock; + struct sockaddr_in localAddr = {0}; + struct sockaddr_in remoteAddr = {0}; + struct linger linger_opt = {1, 15}; + struct hostent *pLookupResult; + + //printf("ObtainAuthToken succedded, token = %s\n", authToken); + printf("-HttpTest- ObtainAuthToken succedded, tokenlen = %d\n", authTokenLen); + + // Send the token to the server + // Open socket + sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (sock != INVALID_SOCKET) + { + // Setup the local address structure + localAddr.sin_family = AF_INET; + localAddr.sin_addr.s_addr = htonl(INADDR_ANY); + + // Bind socket + if (!bind(sock, (const struct sockaddr*) &localAddr, sizeof(struct sockaddr_in))) + { + // Resolve the server address + pLookupResult = gethostbyname(pServerAddress); + if (pLookupResult) + { + // Validate the address type returned + if (pLookupResult->h_addrtype == AF_INET) + { + int numAddressesFound = 0; + + // Determine how many addresses where returned + while (pLookupResult->h_addr_list[numAddressesFound] != NULL) + { + //printf("ServerAddress = %08X\n", *((int*) pLookupResult->h_addr_list[numAddressesFound])); + numAddressesFound ++; + } + //printf("Found %d addresses\n", numAddressesFound); + + + // Setup the remote address structure with the lookup results + remoteAddr.sin_family = AF_INET; + remoteAddr.sin_port = serverPort; + remoteAddr.sin_addr.s_addr = *((int*) pLookupResult->h_addr_list[0]); // Short-cut + //printf("ServerAddress = %08X\n", remoteAddr.sin_addr.s_addr); + + // Perform connect operation + if (connect(sock, + (struct sockaddr*) &remoteAddr, + sizeof(struct sockaddr_in)) == SOCKET_ERROR) + { + printf("-HttpTest- Connection creation failed, error = %d\n", errno); + } + else + { + char *pBasicCredentials; + char *pEncodedBasicCredentials; + int encodedLength; + char CasaPrincipal[] = "CasaPrincipal:"; + char HTTPReqPart1[] = "GET /example-info HTTP/1.1\r\\nUser-Agent: CasaTestClient\r\nHost: jcstation.dnsdhcp.provo.novell.com:4096\r\nConnection: Keep-Alive\r\nAuthorization: Basic "; + + // Now the connection is setup, send 1st part of HTTP request to the server. + send(sock, HTTPReqPart1, (int) strlen(HTTPReqPart1), 0); + + // Now setup the HTTP Basic Credentials + pBasicCredentials = (char*) malloc(strlen(CasaPrincipal) + strlen(authToken) + 1); + if (pBasicCredentials) + { + memcpy(pBasicCredentials, CasaPrincipal, sizeof(CasaPrincipal)); + strcat(pBasicCredentials, authToken); + + // Now Base64 encode the credentials + if (EncodeData((const void*) pBasicCredentials, + (const int32_t) strlen(pBasicCredentials), + &pEncodedBasicCredentials, + (int32_t *) &encodedLength) == 0) + { + // Send the encoded credentials + send(sock, pEncodedBasicCredentials, encodedLength - 1, 0); + + // Send the rest of the header + send(sock, "\r\n\r\n", 4, 0); + + // Free the buffer holding the encoded credentials + free(pEncodedBasicCredentials); + } + else + { + printf("-HttpTest- Error encoding credentials\n"); + } + + // Free the buffer containing the basic credentials + free(pBasicCredentials); + } + else + { + printf("-HttpTest- Buffer allocation failure\n"); + } + + // Shutdown the connection + shutdown(sock, 0); + } + } + else + { + printf("-HttpTest- Unsupported address type returned %08X\n", pLookupResult->h_addrtype); + } + } + else + { + printf("-HttpTest- Lookup for %s failed\n", pServerAddress); + } + } + else + { + printf("-HttpTest- Unable to bind socket, error = %d", errno); + } + + // Close the socket + setsockopt(sock, SOL_SOCKET, SO_LINGER, (const char*) &linger_opt, sizeof(linger_opt)); + closesocket(sock); + } + else + { + printf("-HttpTest- Unable to open socket, error = %d\n", errno); + } + } +} diff --git a/CASA-auth-token/client/core/test/linux/main.cpp b/CASA-auth-token/client/core/test/linux/main.cpp new file mode 100644 index 00000000..a5f76009 --- /dev/null +++ b/CASA-auth-token/client/core/test/linux/main.cpp @@ -0,0 +1,171 @@ +/*********************************************************************** + * + * 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 + * + ***********************************************************************/ + +#include "platform.h" + + +// Extern functions +extern +void NonHttpTest(void); + +extern +void HttpTest(void); + + +// Globals +char usageString[] = "usage: test -a serverAddress -p serverPort [-s serviceName] [-h]\n"; + +char *pServerAddress = NULL; +int serverPort = 0; +bool execHttpTest = false; + +char serviceName[] = "testService"; +char *pServiceName = serviceName; + + +/*********************************************************************** + * + * dtoul() + * + ***********************************************************************/ +int +dtoul( + IN char *cp, + IN int len) +{ + int n = 0; + int i; + + for (i = 0; i < len; i++, cp++) + { + // Verify that we are dealing with a valid digit + if (*cp >= '0' && *cp <= '9') + { + n = 10 * n + (*cp - '0'); + } + else + { + printf("-dtoul- Found invalid digit\n"); + break; + } + } + + return n; +} + + +/*********************************************************************** + * + * main() + * + ***********************************************************************/ +int main(int argc, char* argv[]) +{ + // Process input parameters + int i = 1; + while(argv[i] != NULL) + { + if (strcasecmp(argv[i], "-a") == 0) + { + // Server Address option, the next argument should + // contain the address. + i++; + if (argv[i] != NULL) + { + pServerAddress = argv[i]; + } + else + { + printf(usageString); + return -1; + } + } + else if (strcasecmp(argv[i], "-p") == 0) + { + // Server port option, the next argument should + // contain the port. + i++; + if (argv[i] != NULL) + { + serverPort = htons(dtoul(argv[i], strlen(argv[i]))); + } + else + { + printf(usageString); + return -1; + } + } + else if (strcasecmp(argv[i], "-s") == 0) + { + // Service name option, the next argument should + // contain the name of the service to be targeted. + i++; + if (argv[i] != NULL) + { + pServiceName = argv[i]; + } + else + { + printf(usageString); + return -1; + } + } + else if (strcasecmp(argv[i], "-h") == 0) + { + // Perform http test option + execHttpTest = true; + } + + // Advance to the next argument + i++; + } + + // Verify that the server address and port were specified + if (pServerAddress && serverPort != 0) + { + // Repeat the test when indicated + printf("Press 'Enter' to run test or 'n + Enter' to stop.\n"); + while(getchar() != 'n') + { + // Execute the appropriate test + if (execHttpTest) + { + HttpTest(); + } + else + { + NonHttpTest(); + } + printf("Press 'Enter' to run test or 'n + Enter' to stop.\n"); + } + } + else + { + printf(usageString); + return -1; + } + + return 0; +} + diff --git a/CASA-auth-token/client/core/test/linux/make.sh b/CASA-auth-token/client/core/test/linux/make.sh new file mode 100755 index 00000000..5b915b65 --- /dev/null +++ b/CASA-auth-token/client/core/test/linux/make.sh @@ -0,0 +1,2 @@ +#!/bin/bash +g++ -o authClientTest ../CASA_Auth.cpp main.cpp -g -DN_PLAT_UNIX -I. -I../../../include -L"../../../lib/Release" -lcasa_c_authtoken -Xlinker -rpath -Xlinker ../../../lib/Release diff --git a/CASA-auth-token/client/core/test/linux/platform.h b/CASA-auth-token/client/core/test/linux/platform.h new file mode 100644 index 00000000..75c9309c --- /dev/null +++ b/CASA-auth-token/client/core/test/linux/platform.h @@ -0,0 +1,54 @@ +/*********************************************************************** + * + * 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 + * + ***********************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "casa_c_authtoken.h" + +// +// Socket Mapping definitions +// +#undef SOCKET +#define SOCKET int +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define LINGER struct linger +#define SOCKADDR_IN struct sockaddr_in +#define closesocket close + diff --git a/CASA-auth-token/client/core/test/windows/main.cpp b/CASA-auth-token/client/core/test/windows/main.cpp new file mode 100644 index 00000000..65ab2b6c --- /dev/null +++ b/CASA-auth-token/client/core/test/windows/main.cpp @@ -0,0 +1,187 @@ +/*********************************************************************** + * + * 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 + * + ***********************************************************************/ + +#include "platform.h" + +// Extern functions +extern +void NonHttpTest(void); + +extern +void HttpTest(void); + + +// Globals +char usageString[] = "usage: test -a serverAddress -p serverPort [-s serviceName] [-h]\n"; + +char *pServerAddress = NULL; +int serverPort = 0; +BOOLEAN execHttpTest = FALSE; + +char serviceName[] = "testService"; +char *pServiceName = serviceName; + + +/*********************************************************************** + * + * dtoul() + * + ***********************************************************************/ +int +dtoul( + IN char *cp, + IN int len) +{ + int n = 0; + int i; + + for (i = 0; i < len; i++, cp++) + { + // Verify that we are dealing with a valid digit + if (*cp >= '0' && *cp <= '9') + { + n = 10 * n + (*cp - '0'); + } + else + { + printf("-dtoul- Found invalid digit\n"); + break; + } + } + + return n; +} + + + + +/*********************************************************************** + * + * main() + * + ***********************************************************************/ +int main(int argc, char* argv[]) +{ + // Process input parameters + int i = 1; + while(argv[i] != NULL) + { + if (stricmp(argv[i], "-a") == 0) + { + // Server Address option, the next argument should + // contain the address. + i++; + if (argv[i] != NULL) + { + pServerAddress = argv[i]; + } + else + { + printf(usageString); + return -1; + } + } + else if (stricmp(argv[i], "-p") == 0) + { + // Server port option, the next argument should + // contain the port. + i++; + if (argv[i] != NULL) + { + serverPort = htons(dtoul(argv[i], (int) strlen(argv[i]))); + } + else + { + printf(usageString); + return -1; + } + } + else if (stricmp(argv[i], "-s") == 0) + { + // Service name option, the next argument should + // contain the name of the service to be targeted. + i++; + if (argv[i] != NULL) + { + pServiceName = argv[i]; + } + else + { + printf(usageString); + return -1; + } + } + else if (stricmp(argv[i], "-h") == 0) + { + // Perform http test option + execHttpTest = TRUE; + } + + // Advance to the next argument + i++; + } + + // Verify that the server address and port were specified + if (pServerAddress && serverPort != 0) + { + int winsockStartupResult; + WSADATA winsockData; + + // First initialize winsock + if ((winsockStartupResult = WSAStartup(MAKEWORD(2,2), &winsockData)) == 0) + { + // Repeat the test when indicated + printf("Press 'Enter' to run test or 'n + Enter' to stop.\n"); + while(getchar() != 'n') + { + // Execute the appropriate test + if (execHttpTest) + { + HttpTest(); + } + else + { + NonHttpTest(); + } + printf("Press 'Enter' to run test or 'n + Enter' to stop.\n"); + } + + // Close winsock + WSACleanup(); + } + else + { + printf("-main- WSAStartup failed, error = %d\n", winsockStartupResult); + } + } + else + { + printf(usageString); + return -1; + } + + return 0; +} + + diff --git a/CASA-auth-token/client/core/test/windows/platform.h b/CASA-auth-token/client/core/test/windows/platform.h new file mode 100644 index 00000000..be4b3d33 --- /dev/null +++ b/CASA-auth-token/client/core/test/windows/platform.h @@ -0,0 +1,29 @@ +/*********************************************************************** + * + * 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 + * + ***********************************************************************/ + +#include +#include +#include "casa_c_authtoken.h" + +//#define errno WSAGetLastError() diff --git a/CASA-auth-token/client/core/test/windows/test.vcproj b/CASA-auth-token/client/core/test/windows/test.vcproj new file mode 100644 index 00000000..bf016d2e --- /dev/null +++ b/CASA-auth-token/client/core/test/windows/test.vcproj @@ -0,0 +1,145 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CASA-auth-token/client/core/util.c b/CASA-auth-token/client/core/util.c new file mode 100644 index 00000000..b93a5508 --- /dev/null +++ b/CASA-auth-token/client/core/util.c @@ -0,0 +1,321 @@ +/*********************************************************************** + * + * 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 + * + ***********************************************************************/ + +//===[ Include files ]===================================================== + +#include "internal.h" + +//===[ Type definitions ]================================================== + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + +// Tables for Base64 encoding and decoding +static const int8_t g_Base64[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +static const uint8_t g_Expand64[256] = +{ + /* ASCII table */ + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64, + 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64, + 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 +}; + + +//++======================================================================= +CasaStatus +EncodeData( + IN const void *pData, + IN const int32_t dataLen, + INOUT char **ppEncodedData, + INOUT int32_t *pEncodedDataLen) +// +// Arguments: +// +// Returns: +// +// Description: +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus; + int encodedSize; + + char *pTmp; + + DbgTrace(3, "-EncodeData- Start\n", 0); + + // Determine the encoded size and allocate a buffer to hold the encoded data + encodedSize = ((dataLen * 4 + 2) / 3) - (dataLen % 3 ) + 4; + pTmp = (char*) malloc(encodedSize); + *ppEncodedData = pTmp; + if (*ppEncodedData) + { + uint8_t *pOut, *pIn; + int i; + + // Setup pointers to move through the buffers + pIn = (uint8_t*) pData; + pOut = (uint8_t*) *ppEncodedData; + + // Perform the encoding + for (i = 0; i < dataLen - 2; i += 3) + { + *pOut++ = g_Base64[(pIn[i] >> 2) & 0x3F]; + *pOut++ = g_Base64[((pIn[i] & 0x3) << 4) | + ((int32_t)(pIn[i + 1] & 0xF0) >> 4)]; + *pOut++ = g_Base64[((pIn[i + 1] & 0xF) << 2) | + ((int32_t)(pIn[i + 2] & 0xC0) >> 6)]; + *pOut++ = g_Base64[pIn[i + 2] & 0x3F]; + } + if (i < dataLen) + { + *pOut++ = g_Base64[(pIn[i] >> 2) & 0x3F]; + if (i == (dataLen - 1)) + { + *pOut++ = g_Base64[((pIn[i] & 0x3) << 4)]; + *pOut++ = '='; + } + else + { + *pOut++ = g_Base64[((pIn[i] & 0x3) << 4) | + ((int32_t)(pIn[i + 1] & 0xF0) >> 4)]; + *pOut++ = g_Base64[((pIn[i + 1] & 0xF) << 2)]; + } + *pOut++ = '='; + } + *pOut++ = '\0'; + + // Return the encoded data length + *pEncodedDataLen = (int32_t)(pOut - (uint8_t*)*ppEncodedData); + + // Success + retStatus = CASA_STATUS_SUCCESS; + } + else + { + DbgTrace(0, "-EncodeData- Buffer allocation failure\n", 0); + + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + + DbgTrace(3, "-EncodeData- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +CasaStatus +DecodeData( + IN const char *pEncodedData, + IN const int32_t encodedDataLen, // Does not include NULL terminator + INOUT void **ppData, + INOUT int32_t *pDataLen) +// +// Arguments: +// +// Returns: +// +// Description: +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus; + int i, j; + int decodedSize; + + DbgTrace(3, "-DecodeData- Start\n", 0); + + // Determine the decoded size + for (i = 0, j = 0; i < encodedDataLen; i++) + if (g_Expand64[((uint8_t*) pEncodedData)[i]] < 64) + j++; + decodedSize = (j * 3 + 3) / 4; + + // Allocate buffer to hold the decoded data + *ppData = malloc(decodedSize); + if (*ppData) + { + bool endReached = false; + uint8_t c0, c1, c2, c3; + uint8_t *p, *q; + + // Initialize parameters that will be used during the decode operation + c0 = c1 = c2 = c3 = 0; + p = (uint8_t*) pEncodedData; + q = (uint8_t*) *ppData; + + // Decode the data + // + // Loop through the data, piecing back information. Any newlines, and/or + // carriage returns need to be skipped. + while (j > 4) + { + while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p))) + p++; + if (64 == g_Expand64[*p]) + { + endReached = true; + break; + } + c0 = *(p++); + + while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p))) + p++; + if (64 == g_Expand64[*p]) + { + *(q++) = (uint8_t)(g_Expand64[c0] << 2); + j--; + endReached = true; + break; + } + c1 = *(p++); + + while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p))) + p++; + if (64 == g_Expand64[*p]) + { + *(q++) = (uint8_t)(g_Expand64[c0] << 2 | g_Expand64[c1] >> 4); + *(q++) = (uint8_t)(g_Expand64[c1] << 4); + j -= 2; + endReached = true; + break; + } + c2 = *(p++); + + while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p))) + p++; + if (64 == g_Expand64[*p]) + { + *(q++) = (uint8_t)(g_Expand64[c0] << 2 | g_Expand64[c1] >> 4); + *(q++) = (uint8_t)(g_Expand64[c1] << 4 | g_Expand64[c2] >> 2); + *(q++) = (uint8_t)(g_Expand64[c2] << 6); + j -= 3; + endReached = true; + break; + } + c3 = *(p++); + + *(q++) = (uint8_t)(g_Expand64[c0] << 2 | g_Expand64[c1] >> 4); + *(q++) = (uint8_t)(g_Expand64[c1] << 4 | g_Expand64[c2] >> 2); + *(q++) = (uint8_t)(g_Expand64[c2] << 6 | g_Expand64[c3]); + j -= 4; + } + if (!endReached) + { + if (j > 1) + *(q++) = (uint8_t)(g_Expand64[*p] << 2 | g_Expand64[p[1]] >> 4); + if (j > 2) + *(q++) = (uint8_t)(g_Expand64[p[1]] << 4 | g_Expand64[p[2]] >> 2); + if (j > 3) + *(q++) = (uint8_t)(g_Expand64[p[2]] << 6 | g_Expand64[p[3]]); + } + + // Return the length of the decoded data + *pDataLen = (int32_t)(q - (uint8_t*)*ppData); + + // Success + retStatus = CASA_STATUS_SUCCESS; + } + else + { + DbgTrace(0, "-DecodeData- Buffer allocation failure\n", 0); + + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + + DbgTrace(3, "-DecodeData- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +int +dtoul( + IN const char *cp, + IN const int len) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + int n = 0; + int i; + + DbgTrace(2, "-dtoul- Start\n", 0); + + for (i = 0; i < len; i++, cp++) + { + // Verify that we are dealing with a valid digit + if (*cp >= '0' && *cp <= '9') + { + n = 10 * n + (*cp - '0'); + } + else + { + DbgTrace(0, "-dtoul- Found invalid digit\n", 0); + break; + } + } + + DbgTrace(2, "-dtoul- End, result = %d\n", n); + + return n; +} + + +//++======================================================================= +//++======================================================================= +//++======================================================================= + diff --git a/CASA-auth-token/client/core/windows/Makefile.am b/CASA-auth-token/client/core/windows/Makefile.am new file mode 100644 index 00000000..4f0e0673 --- /dev/null +++ b/CASA-auth-token/client/core/windows/Makefile.am @@ -0,0 +1,69 @@ +####################################################################### +# +# Copyright (C) 2004 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: Greg Richardson +# +####################################################################### + +SUBDIRS = + +DIST_SUBDIRS = + +EXTRA_DIST = client.vcproj ../*.c *.c *.h *.def + +if DEBUG +TARGET_CFG = Debug +else +TARGET_CFG = Release +endif + +PACKAGE = client +TARGET_FILE = authtoken.dll +LOG_FILE = $(PACKAGE).log + +all-am: $(TARGET_FILE) + +.PHONY: $TARGET_FILE) devenv + +devenv: + @if ! test -x "$(VSINSTALLDIR)/devenv.exe"; then echo "Error: Microsoft Visual Studio .NET is currently required to build MSI and MSM packages"; exit 1; fi + +$(TARGET_FILE): devenv + @rm -f $(LOG_FILE) $@ + @CMD='"$(VSINSTALLDIR)/devenv.exe" ../../auth.sln /build $(TARGET_CFG) /project $(PACKAGE) /out $(LOG_FILE)'; \ + echo $$CMD; \ + if eval $$CMD; then \ + ls -l $(TARGET_CFG)/$(TARGET_FILE); \ + else \ + grep -a "ERROR:" $(LOG_FILE); \ + fi + +package-clean clean-local: + rm -rf Release/* Release Debug/* Debug*/Release */Debug *.log *.suo + +clean: + rm -rf Release/* Release Debug/* Debug */Release */Debug *.log *.suo + +distclean-local: package-clean + rm -f Makefile + +maintainer-clean-local: + rm -f Makefile.in + + + diff --git a/CASA-auth-token/client/core/windows/authtoken.def b/CASA-auth-token/client/core/windows/authtoken.def new file mode 100644 index 00000000..d0c062b8 --- /dev/null +++ b/CASA-auth-token/client/core/windows/authtoken.def @@ -0,0 +1,11 @@ +LIBRARY AUTHTOKEN +DESCRIPTION 'CASA Authentication Token Library.' + + +EXPORTS +; DllRegisterServer PRIVATE +; DllUnregisterServer PRIVATE +; DllGetClassObject PRIVATE + ObtainAuthToken PRIVATE + ObtainAuthTokenEx PRIVATE +; DllCanUnloadNow PRIVATE \ No newline at end of file diff --git a/CASA-auth-token/client/core/windows/client.vcproj b/CASA-auth-token/client/core/windows/client.vcproj new file mode 100644 index 00000000..96c989d3 --- /dev/null +++ b/CASA-auth-token/client/core/windows/client.vcproj @@ -0,0 +1,224 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CASA-auth-token/client/core/windows/dllsup.c b/CASA-auth-token/client/core/windows/dllsup.c new file mode 100644 index 00000000..a0726f5d --- /dev/null +++ b/CASA-auth-token/client/core/windows/dllsup.c @@ -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 + * + ***********************************************************************/ + +//===[ Include files ]===================================================== + +#include "internal.h" +#include +#include +#include "casa_c_authtoken_ex.h" + +//===[ External data ]===================================================== +extern +char clientConfigFolderPartialPath[]; + +extern +char mechConfigFolderPartialPath[]; + +//===[ Manifest constants ]================================================ + +//===[ Type definitions ]================================================== + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + +UINT32 g_ulCount = 0; +UINT32 g_ulLock = 0; +HANDLE g_hModule; +HANDLE g_hModuleMutex; + + +//++======================================================================= +CasaStatus SSCS_CALL +ObtainAuthTokenEx( + IN const char *pServiceName, + IN const char *pHostName, + INOUT char *pAuthTokenBuf, + INOUT int *pAuthTokenBufLen, + IN void *pCredStoreScope) +// +// Arguments: +// pServiceName - +// Pointer to NULL terminated string that contains the +// name of the service to which the client is trying to +// authenticate. +// +// pHostName - +// Pointer to NULL terminated string that contains the +// name of the host where resides the service to which the +// client is trying to authenticate. Note that the name +// can either be a DNS name or a dotted IP address. +// +// pAuthTokenBuf - +// Pointer to buffer that will receive the authentication +// token. The length of this buffer is specified by the +// pAuthTokenBufLen parameter. Note that the the authentication +// token will be in the form of a NULL terminated string. +// +// pAuthTokenBufLen - +// Pointer to integer that contains the length of the +// buffer pointed at by pAuthTokenBuf. Upon return of the +// function, the integer will contain the actual length +// of the authentication token if the function successfully +// completes or the buffer length required if the function +// fails because the buffer pointed at by pAuthTokenBuf is +// not large enough. +// +// pCredStoreScope - +// Pointer to CASA structure for scoping credential store access +// to specific users. This can only be leveraged by applications +// running in the context of System. +// +// Returns: +// Casa Status +// +// Description: +// Get authentication token to authenticate user to specified +// service at host. The user is scoped using the info associated +// with the magic cookie. +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus; + + DbgTrace(1, "-ObtainAuthTokenEx- Start\n", 0); + + // Call our internal worker + retStatus = ObtainAuthTokenInt(pServiceName, + pHostName, + pAuthTokenBuf, + pAuthTokenBufLen, + pCredStoreScope); + + DbgTrace(1, "-ObtainAuthTokenEx- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +BOOL APIENTRY DllMain( + HANDLE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +//=======================================================================-- +{ + BOOL retStatus = TRUE; + char programFilesFolder[MAX_PATH]; + + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + { + g_hModule = hModule; + + // Setup the path to the client and auth mechanisms config folders + if (SHGetFolderPath(NULL, + CSIDL_PROGRAM_FILES, + NULL, + 0, + programFilesFolder) == 0) + { + strcpy(clientConfigFolder, programFilesFolder); + PathAppend(clientConfigFolder, clientConfigFolderPartialPath); + + strcpy(mechConfigFolder, programFilesFolder); + PathAppend(mechConfigFolder, mechConfigFolderPartialPath); + + // Allocate module mutex + g_hModuleMutex = CreateMutex(NULL, FALSE, NULL); + if (! g_hModuleMutex) + { + // Module initialization failed + OutputDebugString("CASAAUTH -DllMain- Failed to create mutex\n"); + retStatus = FALSE; + } + } + else + { + // Failed to obtain the Program Files path + OutputDebugString("CASAAUTH -DllMain- Failed to obtain the Program Files path\n"); + retStatus = FALSE; + } + + break; + } + + case DLL_THREAD_ATTACH: + { + g_hModule = hModule; + break; + } + + case DLL_THREAD_DETACH: + break; + + case DLL_PROCESS_DETACH: + { + /* Don't uninitialize on windows + tbd + */ + break; + } + } + + return retStatus; +} + +//++======================================================================= +// +// DllCanUnloadNow +// +// Synopsis +// +// +STDAPI +DllCanUnloadNow() +// +// Input Arguments +// +// Ouput Arguments +// +// Return Value +// S_OK The DLL can be unloaded. +// S_FALSE The DLL cannot be unloaded now. +// +// Description +// An Exported Function. +// DLLs that support the OLE Component Object Model (COM) should implement +// and export DllCanUnloadNow. +// A call to DllCanUnloadNow determines whether the DLL from which it is +// exported is still in use. A DLL is no longer in use when it is not +// managing any existing objects (the reference count on all of its objects +// is 0). +// DllCanUnloadNow returns S_FALSE if there are any existing references to +// objects that the DLL manages. +// +// Environment +// +// See Also +// +//=======================================================================-- +{ + // tbd + return ((g_ulCount == 0 && g_ulLock == 0) ? S_OK : S_FALSE); +} + +//========================================================================= +//========================================================================= + diff --git a/CASA-auth-token/client/core/windows/platform.c b/CASA-auth-token/client/core/windows/platform.c new file mode 100644 index 00000000..25f2a1c5 --- /dev/null +++ b/CASA-auth-token/client/core/windows/platform.c @@ -0,0 +1,580 @@ +/*********************************************************************** + * + * 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 + * + ***********************************************************************/ + +//===[ Include files ]===================================================== + +#include "internal.h" + +//===[ Type definitions ]================================================== + +// +// Normalized Host Name Cache Entry definition +// +typedef struct _NormalizedHostNameCacheEntry +{ + LIST_ENTRY listEntry; + char *pHostName; + char *pNormalizedHostName; + int buffLengthRequired; + +} NormalizedHostNameCacheEntry, *PNormalizedHostNameCacheEntry; + + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + +// Normalized host name cache list head +static +LIST_ENTRY normalizedHostNameCacheListHead; + +// Synchronization mutex for the normalized host name cache +static +HANDLE hNormalizedHostNameCacheMutex; + +// Client configuration file folder +char clientConfigFolder[MAX_PATH]; +char clientConfigFolderPartialPath[] = "Novell\\Casa\\Etc\\Auth"; + +// Authentication mechanism configuration file folder +char mechConfigFolder[MAX_PATH]; +char mechConfigFolderPartialPath[] = "Novell\\Casa\\Etc\\Auth\\Mechanisms"; + +// Path separator +char pathCharString[] = "\\"; + +//++======================================================================= +CasaStatus +CreateUserMutex( + HANDLE *phMutex + ) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus = CASA_STATUS_SUCCESS; + char *pUsername = NULL; + DWORD nameLength = 0; + + DbgTrace(1, "-CreateUserMutex- Start\n", 0); + + // Get the size of the buffer required to obtain the user name + GetUserName(pUsername, &nameLength); + if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) + { + // Allocate buffer to hold the user name + pUsername = (char*) malloc(nameLength); + if (pUsername) + { + // Get the name of the user + if (GetUserName(pUsername, &nameLength)) + { + SECURITY_ATTRIBUTES mutexAttributes; + char mutexName[256]; + + // Now lets create a global semaphore for the + // user and allow its handle to be inherited. + mutexAttributes.nLength = sizeof(mutexAttributes); + mutexAttributes.lpSecurityDescriptor = NULL; + mutexAttributes.bInheritHandle = TRUE; + if (sprintf(mutexName, "Global\\CASA_Auth_Mutex_%s", pUsername) != -1) + { + *phMutex = CreateMutex(&mutexAttributes, + FALSE, + mutexName); + if (*phMutex == NULL) + { + DbgTrace(0, "-CreateUserMutex- CreateMutex failed, error = %d\n", GetLastError()); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_UNSUCCESSFUL); + } + } + else + { + DbgTrace(0, "-CreateUserMutex- sprintf failed, error = %d\n", GetLastError()); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_UNSUCCESSFUL); + } + } + else + { + DbgTrace(0, "-CreateUserMutex- GetUserName failed, error = %d\n", GetLastError()); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_UNSUCCESSFUL); + } + + // Free the buffer allocated to hold the user name + free(pUsername); + } + else + { + DbgTrace(0, "-CreateUserMutex- Buffer allocation error\n", 0); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + } + else + { + DbgTrace(0, "-CreateUserMutex- Unexpected GetUserName error, error = %d\n", GetLastError()); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_UNSUCCESSFUL); + } + + DbgTrace(1, "-CreateUserMutex- End, retStatus\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +void +AcquireUserMutex( + HANDLE hMutex + ) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + DbgTrace(2, "-AcquireUserMutex- Start\n", 0); + + WaitForSingleObject(hMutex, INFINITE); + + DbgTrace(2, "-AcquireUserMutex- End\n", 0); +} + + +//++======================================================================= +void +ReleaseUserMutex( + HANDLE hMutex + ) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + DbgTrace(2, "-ReleaseUserMutex- Start\n", 0); + + if (ReleaseMutex(hMutex) == 0) + { + DbgTrace(0, "-ReleaseUserMutex- ReleaseMutex failed, error = %d\n", GetLastError()); + } + + DbgTrace(2, "-ReleaseUserMutex- End\n", 0); +} + + +//++======================================================================= +void +DestroyUserMutex( + HANDLE hMutex + ) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + DbgTrace(2, "-DestroyUserMutex- Start\n", 0); + + if (CloseHandle(hMutex) == 0) + { + DbgTrace(0, "-DestroyUserMutex- CloseHandle failed, error = %d\n", GetLastError()); + } + + DbgTrace(2, "-DestroyUserMutex- End\n", 0); +} + + +//++======================================================================= +LIB_HANDLE +OpenLibrary( + IN char *pFileName) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + LIB_HANDLE libHandle; + + DbgTrace(1, "-OpenLibrary- Start\n", 0); + + libHandle = LoadLibrary(pFileName); + if (libHandle == NULL) + { + DbgTrace(0, "-OpenLibrary- Not able to load library, error = %d\n", GetLastError()); + } + + DbgTrace(1, "-OpenLibrary- End, handle = %08X\n", libHandle); + + return libHandle; +} + + +//++======================================================================= +void +CloseLibrary( + IN LIB_HANDLE libHandle) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + DbgTrace(1, "-CloseLibrary- Start\n", 0); + + FreeLibrary(libHandle); + + DbgTrace(1, "-CloseLibrary- End\n", 0); +} + + +//++======================================================================= +void* +GetFunctionPtr( + IN LIB_HANDLE libHandle, + IN char *pFunctionName) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + void *pFuncPtr; + + DbgTrace(1, "-GetFunctionPtr- Start\n", 0); + + pFuncPtr = GetProcAddress(libHandle, pFunctionName); + if (pFuncPtr == NULL) + { + DbgTrace(0, "-GetFunctionPtr- Not able to obtain func ptr, error = %d\n", GetLastError()); + } + + DbgTrace(1, "-GetFunctionPtr- End, pFuncPtr = %08X\n", pFuncPtr); + + return pFuncPtr; +} + + +//++======================================================================= +char* +NormalizeHostName( + IN const char *pHostName) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + char *pNormalizedName = NULL; + LIST_ENTRY *pListEntry; + NormalizedHostNameCacheEntry *pEntry = NULL; + + DbgTrace(1, "-NormalizeHostName- Start\n", 0); + + // Obtain our synchronization mutex + WaitForSingleObject(hNormalizedHostNameCacheMutex, INFINITE); + + // First try to find an entry in the normalized host name cache + // for the host name provided. + pListEntry = normalizedHostNameCacheListHead.Flink; + while (pListEntry != &normalizedHostNameCacheListHead) + { + // Get pointer to the entry + pEntry = CONTAINING_RECORD(pListEntry, NormalizedHostNameCacheEntry, listEntry); + + // Check if the entry is for the host name + if (strcmp(pHostName, pEntry->pHostName) == 0) + { + // This entry corresponds to the given host name + break; + } + else + { + // The entry does not correspond to the given host name + pEntry = NULL; + } + + // Advance to the next entry + pListEntry = pListEntry->Flink; + } + + // Check if we found an entry in our cache for the given host name + if (pEntry) + { + // Entry found, obtain the normalized name from it. + pNormalizedName = (char*) malloc(pEntry->buffLengthRequired); + if (pNormalizedName) + { + // Copy the normalized name onto the allocated buffer + strcpy(pNormalizedName, pEntry->pNormalizedHostName); + } + else + { + DbgTrace(0, "-NormalizeHostName- Buffer allocation error\n", 0); + } + } + else + { + // An entry was not found in our cache, create one. + pEntry = (NormalizedHostNameCacheEntry*) malloc(sizeof(NormalizedHostNameCacheEntry)); + if (pEntry) + { + // Zero the entry + memset(pEntry, 0, sizeof(*pEntry)); + + // Allocate a buffer to hold the host name in the entry + pEntry->pHostName = (char*) malloc(strlen(pHostName) + 1); + if (pEntry->pHostName) + { + struct hostent *pLookupResult; + struct sockaddr_in sockAddr = {0}; + + // Copy the host name given into the allocated buffer + strcpy(pEntry->pHostName, pHostName); + + // Now try to resolve the normalized name + pLookupResult = gethostbyname(pHostName); + if (pLookupResult && pLookupResult->h_addrtype == AF_INET) + { + char dnsHostName[NI_MAXHOST]; + + // Set up a sockaddr structure + sockAddr.sin_family = AF_INET; + sockAddr.sin_addr.S_un.S_addr = *((int*) pLookupResult->h_addr_list[0]); + + // Now try to resolve the name using DNS + if (getnameinfo((const struct sockaddr*) &sockAddr, + sizeof(sockAddr), + dnsHostName, + sizeof(dnsHostName), + NULL, + 0, + NI_NAMEREQD) == 0) + { + // We resolved the address to a DNS name, use it as the normalized name. + pEntry->buffLengthRequired = (int) strlen(dnsHostName) + 1; + pEntry->pNormalizedHostName = (char*) malloc(pEntry->buffLengthRequired); + if (pEntry->pNormalizedHostName) + { + // Copy the dns name + strcpy(pEntry->pNormalizedHostName, dnsHostName); + } + else + { + DbgTrace(0, "-NormalizeHostName- Buffer allocation error\n", 0); + } + } + else + { + DbgTrace(0, "-NormalizeHostName- getnameInfo failed, error %d\n", WSAGetLastError()); + + // Not able to resolve the name in DNS, just use the host name as + // the normalized name. + pEntry->buffLengthRequired = (int) strlen(pHostName) + 1; + pEntry->pNormalizedHostName = (char*) malloc(pEntry->buffLengthRequired); + if (pEntry->pNormalizedHostName) + { + // Copy the host name + strcpy(pEntry->pNormalizedHostName, pHostName); + } + else + { + DbgTrace(0, "-NormalizeHostName- Buffer allocation error\n", 0); + } + } + } + else + { + DbgTrace(0, "-NormalizeHostName- Name resolution failed, error = %d\n", WSAGetLastError()); + } + } + else + { + DbgTrace(0, "-NormalizeHostName- Buffer allocation error\n", 0); + + // Free the space allocated for the entry + free(pEntry); + } + + // Proceed based on whether or not we normalized the name + if (pEntry->pNormalizedHostName) + { + // The name was normalized, save the entry in our cache. + InsertHeadList(&normalizedHostNameCacheListHead, &pEntry->listEntry); + + // Return the normalized name present in the entry + pNormalizedName = (char*) malloc(pEntry->buffLengthRequired); + if (pNormalizedName) + { + // Copy the normalized name onto the allocated buffer + strcpy(pNormalizedName, pEntry->pNormalizedHostName); + } + else + { + DbgTrace(0, "-NormalizeHostName- Buffer allocation error\n", 0); + } + } + else + { + // The host name was not normalized, free allocated resources. + if (pEntry->pHostName) + free(pEntry->pHostName); + free(pEntry); + } + } + else + { + DbgTrace(0, "-NormalizeHostName- Buffer allocation error\n", 0); + } + } + + // Release our synchronization mutex + if (ReleaseMutex(hNormalizedHostNameCacheMutex) == 0) + { + DbgTrace(0, "-NormalizeHostName- ReleaseMutex failed, error\n", 0); + } + + DbgTrace(1, "-NormalizeHostName- End, pNormalizedName = %08X\n", pNormalizedName); + + return pNormalizedName; +} + + +//++======================================================================= +CasaStatus +InitializeHostNameNormalization(void) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_UNSUCCESSFUL); + int winsockStartupResult; + WSADATA winsockData; + + DbgTrace(1, "-InitializeHostNameNormalization- Start\n", 0); + + // Initialize winsock + if ((winsockStartupResult = WSAStartup(MAKEWORD(2,2), &winsockData)) == 0) + { + // Initialize the cache list head + InitializeListHead(&normalizedHostNameCacheListHead); + + // Create a cache mutex only applicable to the current process + hNormalizedHostNameCacheMutex = CreateMutex(NULL, + FALSE, + NULL); + if (hNormalizedHostNameCacheMutex != NULL) + { + retStatus = CASA_STATUS_SUCCESS; + } + else + { + DbgTrace(0, "-InitializeHostNameNormalization- CreateMutex failed, error = %d\n", GetLastError()); + } + } + else + { + DbgTrace(0, "-InitializeHostNameNormalization- WSAStartup failed, error = %d\n", winsockStartupResult); + } + + DbgTrace(1, "-InitializeHostNameNormalization- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +//++======================================================================= +//++======================================================================= + diff --git a/CASA-auth-token/client/core/windows/platform.h b/CASA-auth-token/client/core/windows/platform.h new file mode 100644 index 00000000..c4b03732 --- /dev/null +++ b/CASA-auth-token/client/core/windows/platform.h @@ -0,0 +1,103 @@ +/*********************************************************************** + * + * 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 + * + ***********************************************************************/ + + +//===[ Include files ]===================================================== + +#include +#include +#include +#include +#include +#include +#include + +//===[ Type definitions ]================================================== + +#ifndef CONTAINING_RECORD +#define CONTAINING_RECORD(address, type, field) ((type *)( \ + (char*)(address) - \ + (char*)(&((type *)0)->field))) +#endif + +// +// DbgTrace macro define +// +//#define DbgTrace(LEVEL, X, Y) { \ +//char printBuff[256]; \ +// if (LEVEL == 0 || DebugLevel >= LEVEL) \ +// { \ +// _snprintf(printBuff, sizeof(printBuff), X, Y); \ +// printf("CASA_AuthToken %s", printBuff); \ +// } \ +//} +#define DbgTrace(LEVEL, X, Y) { \ +char formatBuff[128]; \ +char printBuff[256]; \ + if (LEVEL == 0 || DebugLevel >= LEVEL) \ + { \ + strcpy(formatBuff, "CASA_AuthToken "); \ + strncat(formatBuff, X, sizeof(formatBuff) - 10); \ + _snprintf(printBuff, sizeof(printBuff), formatBuff, Y); \ + OutputDebugString(printBuff); \ + } \ +} + +// +// Rpc Session definition +// +typedef struct _RpcSession +{ + HINTERNET hSession; + HINTERNET hConnection; + char *pHostName; + +} RpcSession, *PRpcSession; + + +// +// Other definitions +// +#define LIB_HANDLE HMODULE +#define bool BOOLEAN +#define true TRUE +#define false FALSE + +#define AcquireModuleMutex WaitForSingleObjectEx(g_hModuleMutex, INFINITE, FALSE) +#define ReleaseModuleMutex ReleaseMutex(g_hModuleMutex) + +//===[ Inlines functions ]=============================================== + +//===[ Function prototypes ]=============================================== + +//===[ Global externals ]================================================== + +//===[ External prototypes ]=============================================== + +//===[ External data ]===================================================== + +extern HANDLE g_hModuleMutex; + +//========================================================================= + diff --git a/CASA-auth-token/client/core/windows/rpc.c b/CASA-auth-token/client/core/windows/rpc.c new file mode 100644 index 00000000..e792a883 --- /dev/null +++ b/CASA-auth-token/client/core/windows/rpc.c @@ -0,0 +1,799 @@ +/*********************************************************************** + * + * 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 + * + ***********************************************************************/ + + +//===[ Include files ]===================================================== + +#include "internal.h" + +//===[ Type definitions ]================================================== + +#define INITIAL_RESPONSE_DATA_BUF_SIZE 1028 +#define INCREMENT_RESPONSE_DATA_BUF_SIZE 256 + +#define MAX_RPC_RETRIES 3 + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + +//++======================================================================= +static +CasaStatus +CopyMultiToWideAlloc( + IN char *pMulti, + IN int multiSize, + INOUT LPWSTR *ppWide, + INOUT int *pWideSize) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + int retStatus; + int size, i; + + DbgTrace(2, "-CopyMultiToWideAlloc- Start\n", 0); + + size = (multiSize + 1) * sizeof(WCHAR); + + if ((*ppWide = (PWCHAR) malloc(size)) != NULL) + { + for (i = 0; i < multiSize; i++) + { + *(*ppWide + i) = (unsigned char) *(pMulti + i); + } + + *(*ppWide + i) = L'\0'; + + if (pWideSize) + { + *pWideSize = size - sizeof(WCHAR); + } + + retStatus = CASA_STATUS_SUCCESS; + } + else + { + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + + DbgTrace(2, "-CopyMultiToWideAlloc- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +static +CasaStatus +CopyWideToMultiAlloc( + IN LPWSTR pWide, + IN int wideSize, + INOUT char **ppMulti, + INOUT int *pMultiSize) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + int retStatus; + int size, i; + + DbgTrace(2, "-CopyWideToMultiAlloc- Start\n", 0); + + size = wideSize + 1; + + if ((*ppMulti = malloc(size)) != NULL) + { + for (i = 0; i < wideSize; i++) + { + *(*ppMulti + i) = (char) *(pWide + i); + } + + *(*ppMulti + i) = '\0'; + + if (pMultiSize) + { + *pMultiSize = size - 1; + } + + retStatus = CASA_STATUS_SUCCESS; + } + else + { + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + + DbgTrace(2, "-CopyWideToMultiAlloc- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +RpcSession* +OpenRpcSession( + IN char *pHostName, + IN uint16_t hostPort) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + RpcSession *pSession; + bool success = false; + + DbgTrace(1, "-OpenRpcSession- Start\n", 0); + + // Allocate space for the session + pSession = (RpcSession*) malloc(sizeof(*pSession)); + if (pSession) + { + // Zero the session structure + memset(pSession, 0, sizeof(*pSession)); + + // Save copy of the hostname + pSession->pHostName = malloc(strlen(pHostName) + 1); + if (pSession->pHostName) + { + strcpy(pSession->pHostName, pHostName); + + // Open a Winhttp session + pSession->hSession = WinHttpOpen(L"CASA Client/1.0", + WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, + WINHTTP_NO_PROXY_NAME, + WINHTTP_NO_PROXY_BYPASS, + 0); + if (pSession->hSession) + { + LPWSTR pWideHostName; + int wideHostLen; + + // Session opened, now convert the host name to Unicode so that + // we can open a connection. + if (CopyMultiToWideAlloc(pHostName, + (int) strlen(pHostName), + &pWideHostName, + &wideHostLen) == CASA_STATUS_SUCCESS) + { + // Now open connection + pSession->hConnection = WinHttpConnect(pSession->hSession, + pWideHostName, + hostPort, + 0); + if (pSession->hConnection == NULL) + { + DbgTrace(0, "-OpenRpcSession- Failed to open connection, error = %d\n", GetLastError()); + } + else + { + success = true; + } + + // Free the host name wide string buffer + free(pWideHostName); + } + else + { + DbgTrace(0, "-OpenRpcSession- Error converting host name to wide string\n", 0); + } + } + else + { + DbgTrace(0, "-OpenRpcSession- Failed to open session, error = %d\n", GetLastError()); + } + } + else + { + DbgTrace(0, "-OpenRpcSession- Failed to allocate buffer for host name\n", 0); + } + } + else + { + DbgTrace(0, "-OpenRpcSession- Failed to allocate buffer for rpc session\n", 0); + } + + // Clean up if we did not succeed + if (!success) + { + if (pSession) + { + if (pSession->hConnection) + WinHttpCloseHandle(pSession->hConnection); + + if (pSession->hSession) + WinHttpCloseHandle(pSession->hSession); + + if (pSession->pHostName) + free(pSession->pHostName); + + free(pSession); + pSession = NULL; + } + } + + DbgTrace(2, "-OpenRpcSession- End, pSession = %08X\n", pSession); + + return pSession; +} + + +//++======================================================================= +void +CloseRpcSession( + IN RpcSession *pSession) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + DbgTrace(1, "-CloseRpcSession- Start\n", 0); + + // Close the connection handle + WinHttpCloseHandle(pSession->hConnection); + + // Close the session handle + WinHttpCloseHandle(pSession->hSession); + + // Free hostname buffer if necessary + if (pSession->pHostName) + free(pSession->pHostName); + + // Free the space allocated for the session + free(pSession); + + DbgTrace(1, "-CloseRpcSession- End\n", 0); +} + + +//++======================================================================= +static +void CALLBACK +SecureFailureStatusCallback( + IN HINTERNET hRequest, + IN DWORD *pContext, + IN DWORD internetStatus, + IN LPVOID pStatusInformation, + IN DWORD statusInformationLength) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L0 +//=======================================================================-- +{ + DbgTrace(1, "-SecureFailureStatusCallback- Start\n", 0); + + // Only deal with failures related to certificates + if (internetStatus == WINHTTP_CALLBACK_STATUS_SECURE_FAILURE) + { + // Save the specific failure status + *pContext = *(DWORD*) pStatusInformation; + } + + DbgTrace(1, "-SecureFailureStatusCallback- End\n", 0); +} + + +//++======================================================================= +static +CasaStatus +InternalRpc( + IN RpcSession *pSession, + IN char *pMethod, + IN long flags, + IN char *pRequestData, + INOUT char **ppResponseData, + INOUT int *pResponseDataLen) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ +#define CASA_STATUS_INVALID_SERVER_CERTIFICATE CASA_STATUS_UNSUCCESSFUL // temporary until casa_status.h is updated + + CasaStatus retStatus = CASA_STATUS_SUCCESS; + char rpcTarget[256]; + LPWSTR pWideRpcTarget; + int wideRpcTargetLen; + WCHAR sendHeaders[] = L"Content-Type: text/html"; + DWORD securityFailureStatusFlags; + int retriesAllowed = 1; + bool attemptRetry; + + DbgTrace(1, "-InternalRpc- Start\n", 0); + + // Initialize output parameter + *ppResponseData = NULL; + + // Create rpc target string and convert it to a wide string + sprintf(rpcTarget, "CasaAuthTokenSvc/Rpc?method=%s", pMethod); + retStatus = CopyMultiToWideAlloc(rpcTarget, + (int) strlen(rpcTarget), + &pWideRpcTarget, + &wideRpcTargetLen); + if (CASA_SUCCESS(retStatus)) + { + HINTERNET hRequest; + + do + { + // Forget about having been told to retry + attemptRetry = false; + + // Open a request handle + hRequest = WinHttpOpenRequest(pSession->hConnection, + L"POST", + pWideRpcTarget, + NULL, + WINHTTP_NO_REFERER, + WINHTTP_DEFAULT_ACCEPT_TYPES, + flags & SECURE_RPC_FLAG? WINHTTP_FLAG_REFRESH | WINHTTP_FLAG_SECURE : WINHTTP_FLAG_REFRESH); + if (hRequest) + { + int reqDataLen = (int) strlen(pRequestData); + + // Check if we need to set options to deal with secure connections + if (flags & SECURE_RPC_FLAG) + { + // We are using secure connections, now proceed based on whether or not + // we are configured to allow invalid certificates. + if (flags & ALLOW_INVALID_CERTS_RPC_FLAG + || (flags & ALLOW_INVALID_CERTS_USER_APPROVAL_RPC_FLAG + && InvalidCertsFromHostAllowed(pSession->pHostName))) + { + DWORD secFlags = SECURITY_FLAG_IGNORE_CERT_CN_INVALID | SECURITY_FLAG_IGNORE_UNKNOWN_CA; + + // We are configured to allow invalid certificates, inform the HTTP stack. + if (WinHttpSetOption(hRequest, + WINHTTP_OPTION_SECURITY_FLAGS, + &secFlags, + sizeof(secFlags)) == FALSE) + { + DbgTrace(0, "-InternalRpc- Failed setting options to ignore invalid certs, error = %d\n", GetLastError()); + } + } + else + { + // We are not configured to allow invalid certificates, set a callback handler + // to detect invalid certificate conditions. + if (WinHttpSetStatusCallback(hRequest, + SecureFailureStatusCallback, + WINHTTP_CALLBACK_FLAG_SECURE_FAILURE, + (DWORD_PTR) NULL) == WINHTTP_INVALID_STATUS_CALLBACK) + { + DbgTrace(0, "-InternalRpc- Failed setting status callback, error = %d\n", GetLastError()); + } + } + } + + // Send the request + securityFailureStatusFlags = 0; + if (WinHttpSendRequest(hRequest, + sendHeaders, + -1, + pRequestData, + reqDataLen, + reqDataLen, + (DWORD_PTR) &securityFailureStatusFlags)) + { + // Request sent, now await for the response. + if (WinHttpReceiveResponse(hRequest, NULL)) + { + WCHAR httpCompStatus[4] = {0}; + DWORD httpCompStatusLen = sizeof(httpCompStatus); + + // Response received, make sure that it completed successfully. + if (WinHttpQueryHeaders(hRequest, + WINHTTP_QUERY_STATUS_CODE, + NULL, + &httpCompStatus, + &httpCompStatusLen, + WINHTTP_NO_HEADER_INDEX)) + { + // Check that the request completed successfully + if (memcmp(httpCompStatus, L"200", sizeof(httpCompStatus)) == 0) + { + char *pResponseData; + int responseDataBufSize = INITIAL_RESPONSE_DATA_BUF_SIZE; + int responseDataRead = 0; + + // Now read the response data, to do so we need to allocate a buffer. + pResponseData = (char*) malloc(INITIAL_RESPONSE_DATA_BUF_SIZE); + if (pResponseData) + { + char *pCurrLocation = pResponseData; + DWORD bytesRead; + + do + { + bytesRead = 0; + if (WinHttpReadData(hRequest, + (LPVOID) pCurrLocation, + responseDataBufSize - responseDataRead, + &bytesRead)) + { + pCurrLocation += bytesRead; + responseDataRead += bytesRead; + + // Check if we need to allocate a larger buffer + if (responseDataRead == responseDataBufSize) + { + char *pTmpBuf; + + // We need to upgrade the receive buffer + pTmpBuf = (char*) malloc(responseDataBufSize + INCREMENT_RESPONSE_DATA_BUF_SIZE); + if (pTmpBuf) + { + memcpy(pTmpBuf, pResponseData, responseDataBufSize); + free(pResponseData); + pResponseData = pTmpBuf; + pCurrLocation = pResponseData + responseDataBufSize; + responseDataBufSize += INCREMENT_RESPONSE_DATA_BUF_SIZE; + } + else + { + DbgTrace(0, "-InternalRpc- Buffer allocation failure\n", 0); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + } + } + else + { + DbgTrace(0, "-InternalRpc- Failed reading response data, error = %d\n", GetLastError()); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_UNSUCCESSFUL); + } + } while (CASA_SUCCESS(retStatus) + && bytesRead != 0); + + // Check if the response data was successfully received + if (CASA_SUCCESS(retStatus)) + { + // The response data was received, return it to the caller. + *ppResponseData = pResponseData; + *pResponseDataLen = responseDataRead; + } + else + { + // Failed to receive the response data, free the allocated buffer. + free(pResponseData); + } + } + else + { + DbgTrace(0, "-InternalRpc- Buffer allocation failure\n", 0); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + } + else + { + DbgTrace(0, "-InternalRpc- HTTP request did not complete successfully, status = %S\n", httpCompStatus); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_UNSUCCESSFUL); + } + } + else + { + DbgTrace(0, "-InternalRpc- Unable to obtain http request completion status, error = %d\n", GetLastError()); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_UNSUCCESSFUL); + } + } + else + { + DbgTrace(0, "-InternalRpc- Unable to receive response, error = %d\n", GetLastError()); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_UNSUCCESSFUL); + } + } + else + { + int error = GetLastError(); + + if (error == ERROR_WINHTTP_CANNOT_CONNECT) + { + DbgTrace(0, "-InternalRpc- Unable to connect to server\n", 0); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_AUTH_SERVER_UNAVAILABLE); + } + else if (error == ERROR_WINHTTP_SECURE_FAILURE) + { + DbgTrace(1, "-InternalRpc- Secure connection failure, flags = %0x\n", securityFailureStatusFlags); + + // Try to deal with the issue + if ((securityFailureStatusFlags & ~(WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA + | WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID + | WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID)) == 0 + && flags & ALLOW_INVALID_CERTS_USER_APPROVAL_RPC_FLAG) + { + WINHTTP_CERTIFICATE_INFO certInfo; + DWORD certInfoLen = sizeof(certInfo); + + // The failure was due to an invalid CN, CA, or both. + // + // Obtain information about the server certificate to give user + // the choice of accepting it. + if (WinHttpQueryOption(hRequest, + WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT, + &certInfo, + &certInfoLen) + && certInfo.lpszSubjectInfo != NULL + && certInfo.lpszIssuerInfo != NULL) + { + char *pSubjectInfo; + int subjectInfoLen; + + // Convert the subjectInfo to multi-byte + retStatus = CopyWideToMultiAlloc(certInfo.lpszSubjectInfo, + (int) wcslen(certInfo.lpszSubjectInfo), + &pSubjectInfo, + &subjectInfoLen); + if (CASA_SUCCESS(retStatus)) + { + char *pIssuerInfo; + int issuerInfoLen; + + // Convert the issuerInfo to multi-byte + retStatus = CopyWideToMultiAlloc(certInfo.lpszIssuerInfo, + (int) wcslen(certInfo.lpszIssuerInfo), + &pIssuerInfo, + &issuerInfoLen); + if (CASA_SUCCESS(retStatus)) + { + long invalidCertFlags = 0; + + // Setup the invalid cert flags + if (securityFailureStatusFlags & WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA) + invalidCertFlags |= INVALID_CERT_CA_FLAG; + + if (securityFailureStatusFlags & WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID) + invalidCertFlags |= INVALID_CERT_CN_FLAG; + + if (securityFailureStatusFlags & WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID) + invalidCertFlags |= INVALID_CERT_DATE_FLAG; + + // Give user the choice to accept the certificate + if (UserApprovedCert(pSession->pHostName, + pSubjectInfo, + pIssuerInfo, + invalidCertFlags)) + { + DbgTrace(1, "-InternalRpc- User approved invalid certificate from %s\n", pSession->pHostName); + + // tbd - Investigate if there is a way to set the accepted certificate in a store so that + // it can be utilized by the SSL stack directly. This would be a better method for dealing with + // this issue. + + AllowInvalidCertsFromHost(pSession->pHostName); + + // Try to retry the request + attemptRetry = true; + } + else + { + DbgTrace(1, "-InternalRpc- User did not approve invalid certificate from %s\n", pSession->pHostName); + + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_INVALID_SERVER_CERTIFICATE); + } + + // Free the buffer containing the issuerInfo + free(pIssuerInfo); + } + + // Free the buffer containing the subjectInfo + free(pSubjectInfo); + } + + // Free necessary certificate information + if (certInfo.lpszSubjectInfo) LocalFree(certInfo.lpszSubjectInfo); + if (certInfo.lpszIssuerInfo) LocalFree(certInfo.lpszIssuerInfo); + if (certInfo.lpszProtocolName) LocalFree(certInfo.lpszProtocolName); + if (certInfo.lpszSignatureAlgName) LocalFree(certInfo.lpszSignatureAlgName); + if (certInfo.lpszEncryptionAlgName) LocalFree(certInfo.lpszEncryptionAlgName); + } + else + { + DbgTrace(0, "-InternalRpc- Unable to obtain server certificate struct, error = %0x\n", GetLastError()); + } + } + else + { + // Decided to no give the user a choice to accept invalid server certificate + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_INVALID_SERVER_CERTIFICATE); + } + } + else + { + DbgTrace(0, "-InternalRpc- Unsuccessful send http request, error = %d\n", error); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_UNSUCCESSFUL); + } + } + + // Close the request handle + WinHttpCloseHandle(hRequest); + } + else + { + DbgTrace(0, "-InternalRpc- Unable to open http request, error = %d\n", GetLastError()); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_UNSUCCESSFUL); + } + } while (attemptRetry && retriesAllowed--); + + // Free the rpc target wide string buffer + free(pWideRpcTarget); + } + else + { + DbgTrace(0, "-InternalRpc- Error converting method name to wide string\n", 0); + } + + DbgTrace(1, "-InternalRpc- End, retStatus = %d\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +CasaStatus +Rpc( + IN RpcSession *pSession, + IN char *pMethod, + IN long flags, + IN char *pRequestData, + INOUT char **ppResponseData, + INOUT int *pResponseDataLen) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus; + int retries = 0; + + DbgTrace(1, "-Rpc- Start\n", 0); + + // Retry the RPC as needed + do + { + // Issue the RPC + retStatus = InternalRpc(pSession, + pMethod, + flags, + pRequestData, + ppResponseData, + pResponseDataLen); + + // Account for this try + retries ++; + + } while (CasaStatusCode(retStatus) == CASA_STATUS_AUTH_SERVER_UNAVAILABLE + && retries < MAX_RPC_RETRIES); + + DbgTrace(1, "-Rpc- End, retStatus = %d\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +CasaStatus +InitializeRpc(void) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus = CASA_STATUS_SUCCESS; + + DbgTrace(1, "-InitializeRpc- Start\n", 0); + + // Nothing to do for windows + + DbgTrace(1, "-InitializeRpc- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +//++======================================================================= +//++======================================================================= + diff --git a/CASA-auth-token/client/csharp/Novell.Casa.Authtoken/AssemblyInfo.cs b/CASA-auth-token/client/csharp/Novell.Casa.Authtoken/AssemblyInfo.cs new file mode 100644 index 00000000..2548f91a --- /dev/null +++ b/CASA-auth-token/client/csharp/Novell.Casa.Authtoken/AssemblyInfo.cs @@ -0,0 +1,57 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +// +[assembly: AssemblyTitle("AuthToken Wrapper")] +[assembly: AssemblyDescription("C# Wrapper for Authentication Tokens")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Novell, Inc")] +[assembly: AssemblyProduct("CASA")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +// +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: + +[assembly: AssemblyVersion("1.7.*")] + +// +// In order to sign your assembly you must specify a key to use. Refer to the +// Microsoft .NET Framework documentation for more information on assembly signing. +// +// Use the attributes below to control which key is used for signing. +// +// Notes: +// (*) If no key is specified, the assembly is not signed. +// (*) KeyName refers to a key that has been installed in the Crypto Service +// Provider (CSP) on your machine. KeyFile refers to a file which contains +// a key. +// (*) If the KeyFile and the KeyName values are both specified, the +// following processing occurs: +// (1) If the KeyName can be found in the CSP, that key is used. +// (2) If the KeyName does not exist and the KeyFile does exist, the key +// in the KeyFile is installed into the CSP and used. +// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. +// When specifying the KeyFile, the location of the KeyFile should be +// relative to the project output directory which is +// %Project Directory%\obj\. For example, if your KeyFile is +// located in the project directory, you would specify the AssemblyKeyFile +// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] +// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework +// documentation for more information on this. +// +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile("../../AuthToken.snk")] +[assembly: AssemblyKeyName("")] diff --git a/CASA-auth-token/client/csharp/Novell.Casa.Authtoken/AuthToken.snk b/CASA-auth-token/client/csharp/Novell.Casa.Authtoken/AuthToken.snk new file mode 100644 index 0000000000000000000000000000000000000000..a319b439b3364814c424cd1f1ca6d9af7371b6bb GIT binary patch literal 596 zcmV-a0;~N80ssI2Bme+XQ$aES1ONa50097>KBPAGtY+GH^IdH;O{XoDURcNEA}tV; zRVw%vkeFZ!dfnfC74ZZJb_k9jZzCJaDv2i`t3 z9EcJ{%KQ>-;{x8RnLhz4!k$QwS!&I_>N@7ZyuFN76ZSYsK{04>kDj=T(%<&}$dJ5u zL9WYS@Zx}`2-MyQHSsucI8)q$$cMa#?kfiQq?W_^iDBF0bkLxbIL!;M>{}>0XH;FmVBr< zRad*g(|A-ABfWvYT#B&@Or@V#(6Puv&dL(23m!CE`7}49Q`RN-0u0!t4}~>ARA%%s zatv2quwfwMgU?Q>!BSs#9)VnBVc2FX!tbQA3d}AtXWE^dDj$+bWt-BgX7{! zT~jjA8~G*eL$qC7YJO3;B%usXZ>uBH=rU%*3fq+;rT(GBKuj{g@GX8Nn%8GvLFV$ z+@??})z!?|jK5(?Rw}>oEy?PBm)rB?=%Q!4)s~$Og4`Zo<(pm<#~2+GY)kGehDPJ2 id< + /// Summary description for Class1. + /// + public class Authtoken + { + private const string AUTH_LIBRARY = "C:\\Program Files\\Novell\\CASA\\lib\\authtoken"; + private const int BUFFER_OVERFLOW = 6; + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + public struct LUID + { + public int luidLow; + public int luidHigh; + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + public class SSCS_EXT_T + { + public int extID = 0; // defined to identify the extension + public int version = 0; // defined as the version of the specified extension + public IntPtr ext; // points to the actual extension + } ; + + [DllImport(AUTH_LIBRARY, CharSet=CharSet.None) ] + private static extern int ObtainAuthToken + ( + [In] byte[] baService, + [In] byte[] baHost, + [In, Out] byte[] baToken, + [In, Out] ref int iTokenLength + ); + + [DllImport(AUTH_LIBRARY, CharSet=CharSet.None) ] + private static extern int ObtainAuthTokenEx + ( + [In] byte[] baService, + [In] byte[] baHost, + [In, Out] byte[] baToken, + [In, Out] ref int iTokenLength, + [In] SSCS_EXT_T ext + ); + + + public Authtoken() + { + } + + + public static byte[] ObtainAuthToken(string sService, string sHost) + { + return ObtainAuthToken(sService, sHost, null); + } + + public static byte[] ObtainAuthToken(string sService, string sHost, WinLuid luid) + { + int rcode = 0; + byte[] baService = null; + byte[] baHost = null; + int bufferSize = 0; + bool bLuidPassedIn = false; + + byte[] baToken = new byte[bufferSize]; + + // convert service to ascii byte array + if (sService != null) + { + baService = Encoding.ASCII.GetBytes(sService); + } + else + { + throw new Exception("Invalid parameter"); + } + + // convert host to ascii byte array + if (sHost != null) + { + baHost = Encoding.ASCII.GetBytes(sHost); + } + else + { + throw new Exception("Invalid parameter"); + } + + + SSCS_EXT_T ext = new SSCS_EXT_T(); + if ((luid.GetHighPart() != 0) || (luid.GetLowPart() != 0)) + { + // allocate a structure to marshal + LUID sluid = new LUID(); + sluid.luidHigh = luid.GetHighPart(); + sluid.luidLow = luid.GetLowPart(); + + ext.extID = 1; + ext.version = 1; + ext.ext = Marshal.AllocHGlobal(Marshal.SizeOf(sluid)); + + Marshal.StructureToPtr(sluid, ext.ext, false); + bLuidPassedIn = true; + } + + + // call with buffersize of 0. This way we determine the exact size. + try + { + if (bLuidPassedIn) + { + rcode = ObtainAuthTokenEx(baService, baHost, baToken, ref bufferSize, ext); + } + else + { + rcode = ObtainAuthToken(baService, baHost, baToken, ref bufferSize); + } + + int test = (rcode & BUFFER_OVERFLOW); + if (test == BUFFER_OVERFLOW) + { + // now allocate the proper size + baToken = new byte[bufferSize]; + rcode = ObtainAuthToken(baService, baHost, baToken, ref bufferSize); + } + } + catch (Exception e) + { + LogMessage(e.ToString()); + return null; + } + + if (ext.ext != IntPtr.Zero) + Marshal.FreeHGlobal(ext.ext); + + if (rcode != 0) + { + throw new Exception(rcode.ToString()); + } + else + { + return baToken; + } + } + + private static void LogMessage(string sMessage) + { + System.Diagnostics.Trace.WriteLine("(C#)AuthToken: " + sMessage); + } + } +} diff --git a/CASA-auth-token/client/csharp/Novell.Casa.Authtoken/Novell.Casa.Client.csproj b/CASA-auth-token/client/csharp/Novell.Casa.Authtoken/Novell.Casa.Client.csproj new file mode 100644 index 00000000..89da51ec --- /dev/null +++ b/CASA-auth-token/client/csharp/Novell.Casa.Authtoken/Novell.Casa.Client.csproj @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CASA-auth-token/client/csharp/Novell.Casa.Authtoken/WinLuid.cs b/CASA-auth-token/client/csharp/Novell.Casa.Authtoken/WinLuid.cs new file mode 100644 index 00000000..bb7e753d --- /dev/null +++ b/CASA-auth-token/client/csharp/Novell.Casa.Authtoken/WinLuid.cs @@ -0,0 +1,29 @@ +using System; + +namespace Novell.Casa.Client.Auth +{ + /// + /// Summary description for WinLuid. + /// + public class WinLuid + { + private int m_low = 0; + private int m_high = 0; + + public WinLuid(int lowPart, int highPart ) + { + m_low = lowPart; + m_high = highPart; + } + + public int GetLowPart() + { + return m_low; + } + + public int GetHighPart() + { + return m_high; + } + } +} diff --git a/CASA-auth-token/client/csharp/README b/CASA-auth-token/client/csharp/README new file mode 100644 index 00000000..2fb1d8e2 --- /dev/null +++ b/CASA-auth-token/client/csharp/README @@ -0,0 +1,68 @@ +/*********************************************************************** + * + * 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 Novell.Casa.Client.Auth CSHARP Library + * + ***********************************************************************/ + +INTRODUCTION + +Novell.Casa.Client.Auth CSHARP Library provides a class for CSHARP client +applications to obtain authentication tokens from the CASA Authentication +Token Infrastructure. + +CLIENT APPLICATION PROGRAMMING NOTES + +The Novell.Casa.Client.Auth.Authtoken class provides static method ObtainAuthToken() +to allow client applications to obtain CASA Authentication Tokens. The caller must +supply the name of the service to which it wants to authenticate along with the name +of the host where it resides to the static method. The returned authentication token +is a Base64 encoded string. + +Applications utilizing CASA Authentication Tokens as passwords in protocols that require the +transfer of user name and password credentials should verify or remove any password length limits +as the length of CASA Authentication Tokens may be over 1K bytes. The size of the CASA Authentication +Tokens is directly dependent on the amount of identity information configured as required by the +consuming service. These applications should also set the user name to "CasaPrincipal". + +For examples of code which uses the Novell.Casa.Client.Auth.Authtoken class look at the test +application under the test folder. + +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/client/csharp/TODO b/CASA-auth-token/client/csharp/TODO new file mode 100644 index 00000000..41061da2 --- /dev/null +++ b/CASA-auth-token/client/csharp/TODO @@ -0,0 +1,15 @@ +/*********************************************************************** + * + * TODO for Novell.Casa.Client.Auth CSHARP Library + * + ***********************************************************************/ + +INTRODUCTION + +This file contains a list of the items still outstanding for the +Novell.Casa.Client.Auth CSHARP library. + +OUTSTANDING ITEMS + +- Include it in the Linux Client build/rpm. + diff --git a/CASA-auth-token/client/csharp/test/App.ico b/CASA-auth-token/client/csharp/test/App.ico new file mode 100644 index 0000000000000000000000000000000000000000..3a5525fd794f7a7c5c8e6187f470ea3af38cd2b6 GIT binary patch literal 1078 zcmeHHJr05}7=1t!Hp3A*8IHkVf+j?-!eHY14Gtcw1Eb*_9>Bq^zETJ@GKj{_2j4$w zo9}xCh!8{T3=X##Skq>ikMjsvB|y%crWBM2iW(4pI}c%z6%lW!=~4v77#3{z!dmB1 z__&l)-{KUYR+|8|;wB^R|9ET$J@(@=#rd^=)qs85?vAy(PSF5CyNkus435LVkZ$rj zNw|JG-P7^hF<(;#o*Vk}5R#e|^13tBbQkeF?djULtvqyxd3<{9 literal 0 HcmV?d00001 diff --git a/CASA-auth-token/client/csharp/test/AssemblyInfo.cs b/CASA-auth-token/client/csharp/test/AssemblyInfo.cs new file mode 100644 index 00000000..177a4f0e --- /dev/null +++ b/CASA-auth-token/client/csharp/test/AssemblyInfo.cs @@ -0,0 +1,58 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +// +[assembly: AssemblyTitle("")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: + +[assembly: AssemblyVersion("1.0.*")] + +// +// In order to sign your assembly you must specify a key to use. Refer to the +// Microsoft .NET Framework documentation for more information on assembly signing. +// +// Use the attributes below to control which key is used for signing. +// +// Notes: +// (*) If no key is specified, the assembly is not signed. +// (*) KeyName refers to a key that has been installed in the Crypto Service +// Provider (CSP) on your machine. KeyFile refers to a file which contains +// a key. +// (*) If the KeyFile and the KeyName values are both specified, the +// following processing occurs: +// (1) If the KeyName can be found in the CSP, that key is used. +// (2) If the KeyName does not exist and the KeyFile does exist, the key +// in the KeyFile is installed into the CSP and used. +// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. +// When specifying the KeyFile, the location of the KeyFile should be +// relative to the project output directory which is +// %Project Directory%\obj\. For example, if your KeyFile is +// located in the project directory, you would specify the AssemblyKeyFile +// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] +// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework +// documentation for more information on this. +// +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile("")] +[assembly: AssemblyKeyName("")] diff --git a/CASA-auth-token/client/csharp/test/Class1.cs b/CASA-auth-token/client/csharp/test/Class1.cs new file mode 100644 index 00000000..313e455b --- /dev/null +++ b/CASA-auth-token/client/csharp/test/Class1.cs @@ -0,0 +1,74 @@ +/*********************************************************************** + * + * 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: Jim Norman + * + ***********************************************************************/ + +using System; +using Novell.Casa.Client.Auth; + +namespace TestClientAuth +{ + /// + /// Summary description for Class1. + /// + class Class1 + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main(string[] args) + { + if (args.Length < 1) + { + Console.WriteLine("Usage: TestClientAuth [server]"); + Console.WriteLine("Press enter to continue"); + Console.ReadLine(); + return; + } + + try + { + + WinLuid luid = new WinLuid(1234, 5678); + Authtoken.ObtainAuthToken("testService", args[0], luid); + + byte[] baToken = Authtoken.ObtainAuthToken("testService", args[0]); + Console.WriteLine("Token returned: ("+ baToken.Length + ")"); + for (int i=0; i + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CASA-auth-token/client/include/Makefile.am b/CASA-auth-token/client/include/Makefile.am new file mode 100644 index 00000000..f506f2fe --- /dev/null +++ b/CASA-auth-token/client/include/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 = *.h + +.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/client/include/casa_c_authtoken.h b/CASA-auth-token/client/include/casa_c_authtoken.h new file mode 100644 index 00000000..4dd91ad3 --- /dev/null +++ b/CASA-auth-token/client/include/casa_c_authtoken.h @@ -0,0 +1,102 @@ +/*********************************************************************** + * + * 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 + * + ***********************************************************************/ + +#ifndef _CASA_C_AUTHTOKEN_H_ +#define _CASA_C_AUTHTOKEN_H_ + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" +{ +#endif + +//===[ Include files ]===================================================== + +#include +#include + +//===[ Type definitions ]================================================== + +#ifndef SSCS_CALL +#if defined(WIN32) +#define SSCS_CALL __stdcall +#else +#define SSCS_CALL +#endif +#endif + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + + +//++======================================================================= +extern CasaStatus SSCS_CALL +ObtainAuthToken( + IN const char *pServiceName, + IN const char *pHostName, + INOUT char *pAuthTokenBuf, + INOUT int *pAuthTokenBufLen); +// +// Arguments: +// pServiceName - +// Pointer to NULL terminated string that contains the +// name of the service to which the client is trying to +// authenticate. +// +// pHostName - +// Pointer to NULL terminated string that contains the +// name of the host where resides the service to which the +// client is trying to authenticate. Note that the name +// can either be a DNS name or a dotted IP address. +// +// pAuthTokenBuf - +// Pointer to buffer that will receive the authentication +// token. The length of this buffer is specified by the +// pAuthTokenBufLen parameter. Note that the the authentication +// token will be in the form of a NULL terminated string. +// +// pAuthTokenBufLen - +// Pointer to integer that contains the length of the +// buffer pointed at by pAuthTokenBuf. Upon return of the +// function, the integer will contain the actual length +// of the authentication token if the function successfully +// completes or the buffer length required if the function +// fails because the buffer pointed at by pAuthTokenBuf is +// not large enough. +// +// Returns: +// Casa Status +// +// Description: +// Get authentication token to authenticate user to specified +// service at host. +//=======================================================================-- + + +#if defined(__cplusplus) || defined(c_plusplus) +} +#endif // #if defined(__cplusplus) || defined(c_plusplus) + +#endif // #ifndef _CASA_C_AUTHTOKEN_H_ + diff --git a/CASA-auth-token/client/include/list_entry.h b/CASA-auth-token/client/include/list_entry.h new file mode 100644 index 00000000..f482b464 --- /dev/null +++ b/CASA-auth-token/client/include/list_entry.h @@ -0,0 +1,187 @@ +/*********************************************************************** + * + * Copyright (C) 2005-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. + * + ***********************************************************************/ + +#ifndef _LIST_ENTRY_H_ +#define _LIST_ENTRY_H_ + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" +{ +#endif + +//===[ Include files ]===================================================== + +//#include + +//===[ Type definitions ]================================================== + +#ifndef CSAPI +#if defined(WIN32) +#define CSAPI __stdcall +#else +#define CSAPI +#endif +#endif + +#ifndef IN +#define IN +#endif + +#ifndef OUT +#define OUT +#endif + +#ifndef INOUT +#define INOUT +#endif + +#ifndef WIN32 +// +// LIST_ENTRY Type +// Doubly linked list structure +// +typedef struct _LIST_ENTRY +{ + struct _LIST_ENTRY * volatile Flink; + struct _LIST_ENTRY * volatile Blink; +} LIST_ENTRY, *PLIST_ENTRY; +#endif + +//===[ Inlines functions ]=============================================== + +// +// Inline functions for operating on LIST_ENTRY double-linked lists +// + +__inline static void InitializeListHead( + IN PLIST_ENTRY pListEntry ) +{ + pListEntry->Flink = pListEntry->Blink = pListEntry; +} + +__inline static void InsertEntryAfter( + IN PLIST_ENTRY pListEntry, + IN PLIST_ENTRY pAfterEntry ) +{ + pListEntry->Flink = pAfterEntry->Flink; + pListEntry->Blink = pAfterEntry; + pListEntry->Flink->Blink = pAfterEntry->Flink = pListEntry; +} + +__inline static void InsertEntryBefore( + IN PLIST_ENTRY pListEntry, + IN PLIST_ENTRY pBeforeEntry ) +{ + pListEntry->Flink = pBeforeEntry; + pListEntry->Blink = pBeforeEntry->Blink; + pListEntry->Blink->Flink = pBeforeEntry->Blink = pListEntry; +} + +__inline static void InsertHeadList( + IN PLIST_ENTRY pListHead, + IN PLIST_ENTRY pListEntry ) +{ + pListEntry->Blink = pListHead; + pListEntry->Flink = pListHead->Flink; + pListEntry->Flink->Blink = pListHead->Flink = pListEntry; +} + +__inline static void InsertTailList( + IN PLIST_ENTRY pListHead, + IN PLIST_ENTRY pListEntry ) +{ + pListEntry->Flink = pListHead; + pListEntry->Blink = pListHead->Blink; + pListEntry->Blink->Flink = pListHead->Blink = pListEntry; +} + +__inline static bool IsListEmpty( + IN PLIST_ENTRY pListHead ) +{ + bool rc = false; + if(pListHead->Flink == pListHead) + rc = true; + return(rc); +} + +__inline static void RemoveEntryList( + IN PLIST_ENTRY pListEntry ) +{ + pListEntry->Flink->Blink = pListEntry->Blink; + pListEntry->Blink->Flink = pListEntry->Flink; + pListEntry->Flink = pListEntry->Blink = (PLIST_ENTRY) 0xbaadf00d; +} + +__inline static PLIST_ENTRY RemoveHeadList( + IN PLIST_ENTRY pListHead ) +{ + PLIST_ENTRY Entry = (PLIST_ENTRY)0; + if(pListHead->Flink != pListHead) + { + Entry = pListHead->Flink; + RemoveEntryList(Entry); + } + return(Entry); +} + +__inline static PLIST_ENTRY RemoveTailList( + IN PLIST_ENTRY pListHead ) +{ + PLIST_ENTRY Entry= (PLIST_ENTRY)0; + if(pListHead->Blink != pListHead) + { + Entry = pListHead->Blink; + RemoveEntryList(Entry); + } + return(Entry); +} + +__inline static PLIST_ENTRY GetFirstListEntry( + IN PLIST_ENTRY pList) +{ + PLIST_ENTRY Entry = (PLIST_ENTRY)0; + if(pList != pList->Flink) + Entry = pList->Flink; + return(Entry); +} + +__inline static PLIST_ENTRY GetNextListEntry( + IN PLIST_ENTRY pList, + IN PLIST_ENTRY pEntry) +{ + PLIST_ENTRY Entry = (PLIST_ENTRY)0; + if(pList != pEntry->Flink) + Entry = pEntry->Flink; + return(Entry); +} + + +//========================================================================= + + +#if defined(__cplusplus) || defined(c_plusplus) +} +#endif // #if defined(__cplusplus) || defined(c_plusplus) + +#endif // #ifndef _LIST_ENTRY_H_ + + diff --git a/CASA-auth-token/client/include/proto.h b/CASA-auth-token/client/include/proto.h new file mode 100644 index 00000000..87b90eb1 --- /dev/null +++ b/CASA-auth-token/client/include/proto.h @@ -0,0 +1,70 @@ +/*********************************************************************** + * + * 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 + * + ***********************************************************************/ + +#ifndef _PROTO_H_ +#define _PROTO_H_ + +//===[ Include files ]===================================================== + + +//===[ Type definitions ]================================================== + +// +// XML Constants for the documents exchanged between the CASA Client +// and the CASA Server. +// +#define XML_DECLARATION "" +#define AUTH_REQUEST_ELEMENT_NAME "auth_req" +#define AUTH_RESPONSE_ELEMENT_NAME "auth_resp" +#define GET_AUTH_POLICY_REQUEST_ELEMENT_NAME "get_auth_policy_req" +#define GET_AUTH_POLICY_RESPONSE_ELEMENT_NAME "get_auth_policy_resp" +#define GET_AUTH_TOKEN_REQUEST_ELEMENT_NAME "get_auth_tok_req" +#define GET_AUTH_TOKEN_RESPONSE_ELEMENT_NAME "get_auth_tok_resp" +#define AUTH_MECH_TOKEN_ELEMENT_NAME "auth_mech_token" +#define AUTH_TOKEN_ELEMENT_NAME "auth_token" +#define AUTH_POLICY_ELEMENT_NAME "auth_policy" +#define AUTH_SOURCE_ELEMENT_NAME "auth_source" +#define STATUS_ELEMENT_NAME "status" +#define SESSION_TOKEN_ELEMENT_NAME "session_token" +#define LIFETIME_ELEMENT_NAME "lifetime" +#define DESCRIPTION_ELEMENT_NAME "description" +#define SERVICE_ELEMENT_NAME "service" +#define HOST_ELEMENT_NAME "host" +#define REALM_ELEMENT_NAME "realm" +#define MECHANISM_ELEMENT_NAME "mechanism" +#define MECHANISM_INFO_ELEMENT_NAME "mechanism_info" +#define SIGNATURE_ELEMENT_NAME "signature" +#define TYPE_ELEMENT_NAME "type" +#define IDENTITY_TOKEN_ELEMENT_NAME "ident_token" + +// +// HTTP Status Codes +// +#define HTTP_OK_STATUS_CODE "200" +#define HTTP_UNAUTHORIZED_STATUS_CODE "401" +#define HTTP_NOT_FOUND_STATUS_CODE "404" +#define HTTP_SERVER_ERROR_STATUS_CODE "500" + + +#endif // _PROTO_H_ diff --git a/CASA-auth-token/client/include/windows/casa_c_authtoken_ex.h b/CASA-auth-token/client/include/windows/casa_c_authtoken_ex.h new file mode 100644 index 00000000..76960715 --- /dev/null +++ b/CASA-auth-token/client/include/windows/casa_c_authtoken_ex.h @@ -0,0 +1,109 @@ +/*********************************************************************** + * + * 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 + * + ***********************************************************************/ + +#ifndef _CASA_C_AUTHTOKEN_EX_H_ +#define _CASA_C_AUTHTOKEN_EX_H_ + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" +{ +#endif + +//===[ Include files ]===================================================== + +#include +#include + +//===[ Type definitions ]================================================== + +#ifndef SSCS_CALL +#if defined(WIN32) +#define SSCS_CALL __stdcall +#else +#define SSCS_CALL +#endif +#endif + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + + +//++======================================================================= +CasaStatus SSCS_CALL +ObtainAuthTokenEx( + IN const char *pServiceName, + IN const char *pHostName, + INOUT char *pAuthTokenBuf, + INOUT int *pAuthTokenBufLen, + IN void *pCredStoreScope); +// +// Arguments: +// pServiceName - +// Pointer to NULL terminated string that contains the +// name of the service to which the client is trying to +// authenticate. +// +// pHostName - +// Pointer to NULL terminated string that contains the +// name of the host where resides the service to which the +// client is trying to authenticate. Note that the name +// can either be a DNS name or a dotted IP address. +// +// pAuthTokenBuf - +// Pointer to buffer that will receive the authentication +// token. The length of this buffer is specified by the +// pAuthTokenBufLen parameter. Note that the the authentication +// token will be in the form of a NULL terminated string. +// +// pAuthTokenBufLen - +// Pointer to integer that contains the length of the +// buffer pointed at by pAuthTokenBuf. Upon return of the +// function, the integer will contain the actual length +// of the authentication token if the function successfully +// completes or the buffer length required if the function +// fails because the buffer pointed at by pAuthTokenBuf is +// not large enough. +// +// pCredStoreScope - +// Pointer to CASA structure for scoping credential store access +// to specific users. This can only be leveraged by applications +// running in the context of System. +// +// Returns: +// Casa Status +// +// Description: +// Get authentication token to authenticate user to specified +// service at host. The user is scoped using the info associated +// with the magic cookie. +//=======================================================================-- + + +#if defined(__cplusplus) || defined(c_plusplus) +} +#endif // #if defined(__cplusplus) || defined(c_plusplus) + +#endif // #ifndef _CASA_C_AUTHTOKEN_EX_H_ + diff --git a/CASA-auth-token/client/package/Makefile.am b/CASA-auth-token/client/package/Makefile.am new file mode 100644 index 00000000..4c1b4130 --- /dev/null +++ b/CASA-auth-token/client/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 = $(TARGET_OS) + +DIST_SUBDIRS = linux windows + +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/client/package/linux/CASA_auth_token_client.changes b/CASA-auth-token/client/package/linux/CASA_auth_token_client.changes new file mode 100644 index 00000000..8629e98d --- /dev/null +++ b/CASA-auth-token/client/package/linux/CASA_auth_token_client.changes @@ -0,0 +1,83 @@ +------------------------------------------------------------------- +Thu Nov 9 17:16:36 MST 2006 - jluciani@novell.com + +- Finished the changes to enable client/ATS communications + over SSL. + +------------------------------------------------------------------- +Tue Nov 7 16:01:11 MST 2006 - jluciani@novell.com + +- Made changes to enable client/ats communication over SSL. (Not quite + done with this yet). + +- Updated the make system to allow Windows builds to be made from + the command line using Cygwin. + +------------------------------------------------------------------- +Thu Oct 19 09:20:24 MDT 2006 - jluciani@novell.com + +- Created client-devel RPM. + +- Made changes to conform to updates made to the Java components + with regard to the layout of files. + +------------------------------------------------------------------- +Tue Oct 10 08:46:22 MDT 2006 - jluciani@novell.com + +- Brought up to date the README and TODO files. + +------------------------------------------------------------------- +Mon Oct 9 09:28:37 MDT 2006 - jluciani@novell.com + +- Cleaned up compiler warnings that were present in some of the + components. + +------------------------------------------------------------------- +Fri Oct 6 14:22:54 MDT 2006 - schoi@novell.com + +- Add the CASA build check as dependency in spec file + +------------------------------------------------------------------- +Thu Oct 5 15:21:39 MDT 2006 - jluciani@novell.com + +- Ported the client to Linux and created the CASA_auth_token_client package. + +------------------------------------------------------------------- +Mon Oct 2 11:47:16 MDT 2006 - jluciani@novell.com + +- Made spec file modifications suggested by SuSE. The changes entailed + leveraging RPM macros instead of using my own scripts to make the + RPM more solid. + +------------------------------------------------------------------- +Thu Sep 14 17:41:40 MDT 2006 - jluciani@novell.com + +- Added rc script for Validate AuthToken Service. + +------------------------------------------------------------------- +Thu Sep 14 09:48:54 MDT 2006 - jluciani@novell.com + +- Created the Validate AuthToken Service and made all of the necessary changes + to allow it to be consumed by the AuthTokenValidate library. + +- Also made necessary spec file changes to support our configuration. + +------------------------------------------------------------------- +Tue Sep 5 08:37:35 MDT 2006 - jluciani@novell.com + +- Created client/server IPC libraries that will be utilized by libcasa_s_authtoken + to communicate with the Java Validate AuthToken Service (yet to be created) over + DOMAIN sockets. The service will utilize the libraries via JNI to be able to + process requests sent using DOMAIN sockets. + +------------------------------------------------------------------- +Tue Aug 15 10:09:32 MDT 2006 - schoi@novell.com +- Fixed CASA_auth_token_devel build requirement for CASA_auth_token_svc + +------------------------------------------------------------------- +Mon Aug 7 10:28:32 MDT 2006 - schoi@novell.com +- This file has been created for CASA_auth_token_native project for the first + time. + +------------------------------------------------------------------- + diff --git a/CASA-auth-token/client/package/linux/CASA_auth_token_native.changes b/CASA-auth-token/client/package/linux/CASA_auth_token_native.changes new file mode 100644 index 00000000..8629e98d --- /dev/null +++ b/CASA-auth-token/client/package/linux/CASA_auth_token_native.changes @@ -0,0 +1,83 @@ +------------------------------------------------------------------- +Thu Nov 9 17:16:36 MST 2006 - jluciani@novell.com + +- Finished the changes to enable client/ATS communications + over SSL. + +------------------------------------------------------------------- +Tue Nov 7 16:01:11 MST 2006 - jluciani@novell.com + +- Made changes to enable client/ats communication over SSL. (Not quite + done with this yet). + +- Updated the make system to allow Windows builds to be made from + the command line using Cygwin. + +------------------------------------------------------------------- +Thu Oct 19 09:20:24 MDT 2006 - jluciani@novell.com + +- Created client-devel RPM. + +- Made changes to conform to updates made to the Java components + with regard to the layout of files. + +------------------------------------------------------------------- +Tue Oct 10 08:46:22 MDT 2006 - jluciani@novell.com + +- Brought up to date the README and TODO files. + +------------------------------------------------------------------- +Mon Oct 9 09:28:37 MDT 2006 - jluciani@novell.com + +- Cleaned up compiler warnings that were present in some of the + components. + +------------------------------------------------------------------- +Fri Oct 6 14:22:54 MDT 2006 - schoi@novell.com + +- Add the CASA build check as dependency in spec file + +------------------------------------------------------------------- +Thu Oct 5 15:21:39 MDT 2006 - jluciani@novell.com + +- Ported the client to Linux and created the CASA_auth_token_client package. + +------------------------------------------------------------------- +Mon Oct 2 11:47:16 MDT 2006 - jluciani@novell.com + +- Made spec file modifications suggested by SuSE. The changes entailed + leveraging RPM macros instead of using my own scripts to make the + RPM more solid. + +------------------------------------------------------------------- +Thu Sep 14 17:41:40 MDT 2006 - jluciani@novell.com + +- Added rc script for Validate AuthToken Service. + +------------------------------------------------------------------- +Thu Sep 14 09:48:54 MDT 2006 - jluciani@novell.com + +- Created the Validate AuthToken Service and made all of the necessary changes + to allow it to be consumed by the AuthTokenValidate library. + +- Also made necessary spec file changes to support our configuration. + +------------------------------------------------------------------- +Tue Sep 5 08:37:35 MDT 2006 - jluciani@novell.com + +- Created client/server IPC libraries that will be utilized by libcasa_s_authtoken + to communicate with the Java Validate AuthToken Service (yet to be created) over + DOMAIN sockets. The service will utilize the libraries via JNI to be able to + process requests sent using DOMAIN sockets. + +------------------------------------------------------------------- +Tue Aug 15 10:09:32 MDT 2006 - schoi@novell.com +- Fixed CASA_auth_token_devel build requirement for CASA_auth_token_svc + +------------------------------------------------------------------- +Mon Aug 7 10:28:32 MDT 2006 - schoi@novell.com +- This file has been created for CASA_auth_token_native project for the first + time. + +------------------------------------------------------------------- + diff --git a/CASA-auth-token/client/package/linux/Makefile.am b/CASA-auth-token/client/package/linux/Makefile.am new file mode 100644 index 00000000..1cace376 --- /dev/null +++ b/CASA-auth-token/client/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_native.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 + diff --git a/CASA-auth-token/client/package/windows/Makefile.am b/CASA-auth-token/client/package/windows/Makefile.am new file mode 100644 index 00000000..7cbf38f2 --- /dev/null +++ b/CASA-auth-token/client/package/windows/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: Greg Richardson +# +####################################################################### + +SUBDIRS = authtokenclient_msm authtokenclient_msi + +DIST_SUBDIRS = authtokenclient_msm authtokenclient_msi + +EXTRA_DIST = + +.PHONY: package package-clean package-install package-uninstall +package package-clean package-install package-uninstall: + $(MAKE) -C authtokenclient_msm $@ + $(MAKE) -C authtokenclient_msi $@ + +clean-local: + if [ -d lib ]; then rm -rf lib; fi + +maintainer-clean-local: + rm -f Makefile.in + diff --git a/CASA-auth-token/client/package/windows/authtokenclient_msi/Makefile.am b/CASA-auth-token/client/package/windows/authtokenclient_msi/Makefile.am new file mode 100644 index 00000000..c97ba445 --- /dev/null +++ b/CASA-auth-token/client/package/windows/authtokenclient_msi/Makefile.am @@ -0,0 +1,69 @@ +####################################################################### +# +# Copyright (C) 2004 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: Greg Richardson +# +####################################################################### + +SUBDIRS = + +DIST_SUBDIRS = + +EXTRA_DIST = authtokenclient_msi.vdproj + +if DEBUG +TARGET_CFG = Debug +else +TARGET_CFG = Release +endif + +PACKAGE = authtokenclient_msi +TARGET_FILE = $(PACKAGE).msi +LOG_FILE = $(PACKAGE).log + +.PHONY: package package-clean package-install package-uninstall devenv + +package: $(TARGET_FILE) + +devenv: + @if ! test -x "$(VSINSTALLDIR)/devenv.exe"; then echo "Error: Microsoft Visual Studio .NET is currently required to build MSI and MSM packages"; exit 1; fi + +$(TARGET_FILE): devenv + @rm -f $(LOG_FILE) $@ + @CMD='"$(VSINSTALLDIR)/devenv.exe" ../../../auth.sln /build $(TARGET_CFG) /project $(PACKAGE) /out $(LOG_FILE)'; \ + echo $$CMD; \ + if eval $$CMD; then \ + ls -l $(TARGET_CFG)/$(TARGET_FILE); \ + else \ + grep -a "ERROR:" $(LOG_FILE); \ + fi + +package-clean clean-local: + rm -rf Release/* Release Debug/* Debug*/Release */Debug *.log *.suo + +clean: + rm -rf Release/* Release Debug/* Debug */Release */Debug *.log *.suo + +distclean-local: package-clean + rm -f Makefile + +maintainer-clean-local: + rm -f Makefile.in + + + diff --git a/CASA-auth-token/client/package/windows/authtokenclient_msi/authtokenclient_msi.vdproj b/CASA-auth-token/client/package/windows/authtokenclient_msi/authtokenclient_msi.vdproj new file mode 100644 index 00000000..9fc83ed1 --- /dev/null +++ b/CASA-auth-token/client/package/windows/authtokenclient_msi/authtokenclient_msi.vdproj @@ -0,0 +1,699 @@ +"DeployProject" +{ +"VSVersion" = "3:701" +"ProjectType" = "8:{2C2AF0D9-9B47-4FE5-BEF2-169778172667}" +"IsWebType" = "8:FALSE" +"ProjectName" = "8:authtokenclient_msi" +"LanguageId" = "3:1033" +"CodePage" = "3:1252" +"UILanguageId" = "3:1033" +"SccProjectName" = "8:" +"SccLocalPath" = "8:" +"SccAuxPath" = "8:" +"SccProvider" = "8:" + "Hierarchy" + { + "Entry" + { + "MsmKey" = "8:_161A15C5C78C4BBD8AEDF896DCFEDE6B" + "OwnerKey" = "8:_634B25C086554FB78146A1549281714E" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_634B25C086554FB78146A1549281714E" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + } + "Configurations" + { + "Debug" + { + "DisplayName" = "8:Debug" + "IsDebugOnly" = "11:TRUE" + "IsReleaseOnly" = "11:FALSE" + "OutputFilename" = "8:Debug\\authtokenclient_msi.msi" + "PackageFilesAs" = "3:2" + "PackageFileSize" = "3:-2147483648" + "CabType" = "3:1" + "Compression" = "3:2" + "SignOutput" = "11:FALSE" + "CertificateFile" = "8:" + "PrivateKeyFile" = "8:" + "TimeStampServer" = "8:" + "InstallerBootstrapper" = "3:2" + } + "Release" + { + "DisplayName" = "8:Release" + "IsDebugOnly" = "11:FALSE" + "IsReleaseOnly" = "11:TRUE" + "OutputFilename" = "8:Release\\authtokenclient_msi.msi" + "PackageFilesAs" = "3:2" + "PackageFileSize" = "3:-2147483648" + "CabType" = "3:1" + "Compression" = "3:2" + "SignOutput" = "11:FALSE" + "CertificateFile" = "8:" + "PrivateKeyFile" = "8:" + "TimeStampServer" = "8:" + "InstallerBootstrapper" = "3:2" + } + } + "Deployable" + { + "CustomAction" + { + } + "DefaultFeature" + { + "Name" = "8:DefaultFeature" + "Title" = "8:" + "Description" = "8:" + } + "ExternalPersistence" + { + "LaunchCondition" + { + "{2522A265-4974-4402-83C5-3B575A2E935A}:_17958A6305A24EF4880B1337DA4FFD51" + { + "Name" = "8:.NET Framework" + "Message" = "8:[VSDNETMSG]" + "SupportedRuntimes" = "8:1.1.4322;2.0.50727" + "InstallUrl" = "8:http://go.microsoft.com/fwlink/?LinkId=9832" + } + } + } + "Feature" + { + } + "File" + { + } + "FileType" + { + } + "Folder" + { + "{78BAF5CE-F2E5-45BE-83BC-DB6AF387E941}:_5822614DE62647039F8AF6B0781851A7" + { + "Name" = "8:#1916" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:DesktopFolder" + "Folders" + { + } + } + "{58C0ADA3-3CEA-43BD-A3B3-2EA121BC8217}:_BADBE39F262C4F79B42417C62DF02E55" + { + "DefaultLocation" = "8:[ProgramFilesFolder][Manufacturer]\\[ProductName]" + "Name" = "8:#1925" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:TARGETDIR" + "Folders" + { + } + } + "{78BAF5CE-F2E5-45BE-83BC-DB6AF387E941}:_CA7A8DC7331A4C47A8C7CDE8C53FE9FA" + { + "Name" = "8:#1919" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:ProgramMenuFolder" + "Folders" + { + } + } + } + "LaunchCondition" + { + } + "Locator" + { + } + "MsiBootstrapper" + { + "LangId" = "3:1033" + } + "Product" + { + "Name" = "8:Microsoft Visual Studio" + "ProductName" = "8:authtokenclient" + "ProductCode" = "8:{6D3AAA36-871A-4427-9311-FC3FE2F17511}" + "PackageCode" = "8:{4F7846D3-7607-463B-8BA7-A76832D29411}" + "UpgradeCode" = "8:{69C5F129-788A-4487-9397-331C0A313A2D}" + "RestartWWWService" = "11:FALSE" + "RemovePreviousVersions" = "11:FALSE" + "DetectNewerInstalledVersion" = "11:TRUE" + "ProductVersion" = "8:1.0.0" + "Manufacturer" = "8:Novell" + "ARPHELPTELEPHONE" = "8:" + "ARPHELPLINK" = "8:" + "Title" = "8:authtokenclient" + "Subject" = "8:" + "ARPCONTACT" = "8:Novell" + "Keywords" = "8:" + "ARPCOMMENTS" = "8:" + "ARPURLINFOABOUT" = "8:" + "ARPPRODUCTICON" = "8:" + "ARPIconIndex" = "3:0" + "SearchPath" = "8:" + "UseSystemSearchPath" = "11:TRUE" + } + "Registry" + { + "HKLM" + { + "Keys" + { + "{6A471EEF-D31B-40F8-BCF6-C9E8EC783F36}:_3C4408A91276415C99DB57B858A91555" + { + "Name" = "8:Software" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + "{6A471EEF-D31B-40F8-BCF6-C9E8EC783F36}:_22714EABC4F3412BB3230B8EA95CFB08" + { + "Name" = "8:[Manufacturer]" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + } + "Values" + { + } + } + } + "Values" + { + } + } + } + } + "HKCU" + { + "Keys" + { + "{6A471EEF-D31B-40F8-BCF6-C9E8EC783F36}:_93C508CBDBB34C95B9C890F165C081F1" + { + "Name" = "8:Software" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + "{6A471EEF-D31B-40F8-BCF6-C9E8EC783F36}:_B7A9FC8108DB4E249F31D12A434C1844" + { + "Name" = "8:[Manufacturer]" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + } + "Values" + { + } + } + } + "Values" + { + } + } + } + } + "HKCR" + { + "Keys" + { + } + } + "HKU" + { + "Keys" + { + } + } + "HKPU" + { + "Keys" + { + } + } + } + "Sequences" + { + } + "Shortcut" + { + } + "UserInterface" + { + "{B654A020-6903-4E6A-A86C-75DC463DB54B}:_1240F250BDDA45B084738491D53CCA13" + { + "UseDynamicProperties" = "11:FALSE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdUserInterface.wim" + } + "{8D9DEE8B-DD8B-4F48-9072-C4364E4F4011}:_2873941BB49A4737AF72ED5E788318F7" + { + "Name" = "8:#1902" + "Sequence" = "3:1" + "Attributes" = "3:3" + "Dialogs" + { + "{18ADD6EC-89FE-4ED7-AD3E-211C40278470}:_10695426506044F6B667E02B3E33A00E" + { + "Sequence" = "3:100" + "DisplayName" = "8:Finished" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdFinishedDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "UpdateText" + { + "Name" = "8:UpdateText" + "DisplayName" = "8:#1058" + "Description" = "8:#1158" + "Type" = "3:15" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1258" + "DefaultValue" = "8:#1258" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{8D9DEE8B-DD8B-4F48-9072-C4364E4F4011}:_353966B93CCA47F89005110A192B33E0" + { + "Name" = "8:#1900" + "Sequence" = "3:2" + "Attributes" = "3:1" + "Dialogs" + { + "{18ADD6EC-89FE-4ED7-AD3E-211C40278470}:_A41DEF6D91134F42BA300A817856F7C2" + { + "Sequence" = "3:300" + "DisplayName" = "8:Confirm Installation" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdAdminConfirmDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{18ADD6EC-89FE-4ED7-AD3E-211C40278470}:_D915672F6CE04B29A5482A7E9297CE42" + { + "Sequence" = "3:100" + "DisplayName" = "8:Welcome" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdAdminWelcomeDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "CopyrightWarning" + { + "Name" = "8:CopyrightWarning" + "DisplayName" = "8:#1002" + "Description" = "8:#1102" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1202" + "DefaultValue" = "8:#1202" + "UsePlugInResources" = "11:TRUE" + } + "Welcome" + { + "Name" = "8:Welcome" + "DisplayName" = "8:#1003" + "Description" = "8:#1103" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1203" + "DefaultValue" = "8:#1203" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{18ADD6EC-89FE-4ED7-AD3E-211C40278470}:_E8BB0C75759A4ECA9292D5EB62A4B1DD" + { + "Sequence" = "3:200" + "DisplayName" = "8:Installation Folder" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdAdminFolderDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{8D9DEE8B-DD8B-4F48-9072-C4364E4F4011}:_72EFC743AB3B42B6994F5EC55E41631F" + { + "Name" = "8:#1901" + "Sequence" = "3:1" + "Attributes" = "3:2" + "Dialogs" + { + "{18ADD6EC-89FE-4ED7-AD3E-211C40278470}:_9D455462808342AE837694F103194C3E" + { + "Sequence" = "3:100" + "DisplayName" = "8:Progress" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdProgressDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "ShowProgress" + { + "Name" = "8:ShowProgress" + "DisplayName" = "8:#1009" + "Description" = "8:#1109" + "Type" = "3:5" + "ContextData" = "8:1;True=1;False=0" + "Attributes" = "3:0" + "Setting" = "3:0" + "Value" = "3:1" + "DefaultValue" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{B654A020-6903-4E6A-A86C-75DC463DB54B}:_A0A8360C0E0D46ACB472E47806B666D5" + { + "UseDynamicProperties" = "11:FALSE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdBasicDialogs.wim" + } + "{8D9DEE8B-DD8B-4F48-9072-C4364E4F4011}:_D708D6BFB2C946BB9BCCC9F6F2CAE0FA" + { + "Name" = "8:#1902" + "Sequence" = "3:2" + "Attributes" = "3:3" + "Dialogs" + { + "{18ADD6EC-89FE-4ED7-AD3E-211C40278470}:_964E18CF17534E789061E20F26EE5EDA" + { + "Sequence" = "3:100" + "DisplayName" = "8:Finished" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdAdminFinishedDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{8D9DEE8B-DD8B-4F48-9072-C4364E4F4011}:_E294259CC9424A6EB901523FCAD0D0CC" + { + "Name" = "8:#1900" + "Sequence" = "3:1" + "Attributes" = "3:1" + "Dialogs" + { + "{18ADD6EC-89FE-4ED7-AD3E-211C40278470}:_E227037047AF41C394E3138699F6DD62" + { + "Sequence" = "3:300" + "DisplayName" = "8:Confirm Installation" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdConfirmDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{18ADD6EC-89FE-4ED7-AD3E-211C40278470}:_EF6CBFADEBBA4F4BA427709FD0C72385" + { + "Sequence" = "3:100" + "DisplayName" = "8:Welcome" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdWelcomeDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "CopyrightWarning" + { + "Name" = "8:CopyrightWarning" + "DisplayName" = "8:#1002" + "Description" = "8:#1102" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1202" + "DefaultValue" = "8:#1202" + "UsePlugInResources" = "11:TRUE" + } + "Welcome" + { + "Name" = "8:Welcome" + "DisplayName" = "8:#1003" + "Description" = "8:#1103" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1203" + "DefaultValue" = "8:#1203" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{8D9DEE8B-DD8B-4F48-9072-C4364E4F4011}:_FC54039B5B444B8C8D7C64B693C25B14" + { + "Name" = "8:#1901" + "Sequence" = "3:2" + "Attributes" = "3:2" + "Dialogs" + { + "{18ADD6EC-89FE-4ED7-AD3E-211C40278470}:_E79C486A92E54E4881FBD841C4649B83" + { + "Sequence" = "3:100" + "DisplayName" = "8:Progress" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdAdminProgressDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "ShowProgress" + { + "Name" = "8:ShowProgress" + "DisplayName" = "8:#1009" + "Description" = "8:#1109" + "Type" = "3:5" + "ContextData" = "8:1;True=1;False=0" + "Attributes" = "3:0" + "Setting" = "3:0" + "Value" = "3:1" + "DefaultValue" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + } + "MergeModule" + { + "{35A69C6E-5BA4-440D-803D-762B59A45393}:_161A15C5C78C4BBD8AEDF896DCFEDE6B" + { + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:TRUE" + "SourcePath" = "8:dotnetfxredist_x86.msm" + "Properties" + { + } + "LanguageId" = "3:1033" + "Exclude" = "11:TRUE" + "Folder" = "8:" + "Feature" = "8:" + "IsolateTo" = "8:" + } + } + "ProjectOutput" + { + "{8062640A-2EEE-46E9-AB67-688E9A886E9F}:_634B25C086554FB78146A1549281714E" + { + "SourcePath" = "8:..\\authtokenclient_msm\\Debug\\authtokenclient_msm.msm" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_BADBE39F262C4F79B42417C62DF02E55" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + "ProjectOutputGroupRegister" = "3:1" + "OutputConfiguration" = "8:" + "OutputGroupCanonicalName" = "8:Built" + "OutputProjectGuid" = "8:{C8405908-5026-4E77-B02F-9259856A17E8}" + "ShowKeyOutput" = "11:TRUE" + "ExcludeFilters" + { + } + "KeyOutputModule" + { + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:..\\authtokenclient_msm\\Debug\\authtokenclient_msm.msm" + "Properties" + { + "_F5F5F604B81645F8B6463F7A7D6A53AD.375AEECA1C3A4EC3AF37E3E5BE6711DD" + { + "Name" = "8:_F5F5F604B81645F8B6463F7A7D6A53AD.375AEECA1C3A4EC3AF37E3E5BE6711DD" + "DisplayName" = "8:Module Retargetable Folder" + "Description" = "8:" + "Type" = "3:32769" + "ContextData" = "8:_RetargetableFolder" + "Attributes" = "3:6" + "Setting" = "3:1" + "UsePlugInResources" = "11:FALSE" + } + } + "LanguageId" = "3:1033" + "Exclude" = "11:FALSE" + "Folder" = "8:_BADBE39F262C4F79B42417C62DF02E55" + "Feature" = "8:" + "IsolateTo" = "8:" + } + } + } + "VJSharpPlugin" + { + } + } +} diff --git a/CASA-auth-token/client/package/windows/authtokenclient_msm/Makefile.am b/CASA-auth-token/client/package/windows/authtokenclient_msm/Makefile.am new file mode 100644 index 00000000..a3982068 --- /dev/null +++ b/CASA-auth-token/client/package/windows/authtokenclient_msm/Makefile.am @@ -0,0 +1,69 @@ +####################################################################### +# +# Copyright (C) 2004 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: Greg Richardson +# +####################################################################### + +SUBDIRS = + +DIST_SUBDIRS = + +EXTRA_DIST = authtokenclient_msm.vdproj + +if DEBUG +TARGET_CFG = Debug +else +TARGET_CFG = Release +endif + +PACKAGE = authtokenclient_msm +TARGET_FILE = $(PACKAGE).msm +LOG_FILE = $(PACKAGE).log + +.PHONY: package package-clean package-install package-uninstall devenv + +package: $(TARGET_FILE) + +devenv: + @if ! test -x "$(VSINSTALLDIR)/devenv.exe"; then echo "Error: Microsoft Visual Studio .NET is currently required to build MSI and MSM packages"; exit 1; fi + +$(TARGET_FILE): devenv + @rm -f $(LOG_FILE) $@ + @CMD='"$(VSINSTALLDIR)/devenv.exe" ../../../auth.sln /build $(TARGET_CFG) /project $(PACKAGE) /out $(LOG_FILE)'; \ + echo $$CMD; \ + if eval $$CMD; then \ + ls -l $(TARGET_CFG)/$(TARGET_FILE); \ + else \ + grep -a "ERROR:" $(LOG_FILE); \ + fi + +package-clean clean-local: + rm -rf Release/* Release Debug/* Debug*/Release */Debug *.log *.suo + +clean: + rm -rf Release/* Release Debug/* Debug */Release */Debug *.log *.suo + +distclean-local: package-clean + rm -f Makefile + +maintainer-clean-local: + rm -f Makefile.in + + + diff --git a/CASA-auth-token/client/package/windows/authtokenclient_msm/authtokenclient_msm.vdproj b/CASA-auth-token/client/package/windows/authtokenclient_msm/authtokenclient_msm.vdproj new file mode 100644 index 00000000..6c292476 --- /dev/null +++ b/CASA-auth-token/client/package/windows/authtokenclient_msm/authtokenclient_msm.vdproj @@ -0,0 +1,647 @@ +"DeployProject" +{ +"VSVersion" = "3:701" +"ProjectType" = "8:{DD7A5B58-C2F9-40FF-B2EF-0773356FB978}" +"IsWebType" = "8:FALSE" +"ProjectName" = "8:authtokenclient_msm" +"LanguageId" = "3:1033" +"CodePage" = "3:1252" +"UILanguageId" = "3:1033" +"SccProjectName" = "8:" +"SccLocalPath" = "8:" +"SccAuxPath" = "8:" +"SccProvider" = "8:" + "Hierarchy" + { + "Entry" + { + "MsmKey" = "8:_191525A919DD46AD8D70B7735EE4F451" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_22FDEF26EDCE4831A621BB20C7EB4508" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_313DE095D13281AF91A64E3F3D472413" + "OwnerKey" = "8:_7A5EA42289F94648877FA695EB1853CE" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_3986DA1502244FFBB04A66472E74633B" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_472FEAD17E7B45FF92E93D80B3379C47" + "OwnerKey" = "8:_8292EFFD84EF46C6BD2F1F3E20808684" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_643B8C25BBD34AD0B405B27E06E03698" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_7A5EA42289F94648877FA695EB1853CE" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_8292EFFD84EF46C6BD2F1F3E20808684" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_92336612AC7D083F97ED302BB7674A2D" + "OwnerKey" = "8:_191525A919DD46AD8D70B7735EE4F451" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_92336612AC7D083F97ED302BB7674A2D" + "OwnerKey" = "8:_3986DA1502244FFBB04A66472E74633B" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_9A3A0F1784E448538A42AE8722C1FE40" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_9AF33A7F4DD64BB58CD561EC8145A8A3" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_9C164F1F2FC0451CA2814BE9BAD532FB" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_B0715A326B76440C90A71D7BB2B61C52" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_E35F46E021184676375C6223ED1BDFCF" + "OwnerKey" = "8:_191525A919DD46AD8D70B7735EE4F451" + "MsmSig" = "8:_UNDEFINED" + } + } + "Configurations" + { + "Debug" + { + "DisplayName" = "8:Debug" + "IsDebugOnly" = "11:TRUE" + "IsReleaseOnly" = "11:FALSE" + "OutputFilename" = "8:Debug\\authtokenclient_msm.msm" + "PackageFilesAs" = "3:2" + "PackageFileSize" = "3:-2147483648" + "CabType" = "3:1" + "Compression" = "3:2" + "SignOutput" = "11:FALSE" + "CertificateFile" = "8:" + "PrivateKeyFile" = "8:" + "TimeStampServer" = "8:" + "InstallerBootstrapper" = "3:1" + } + "Release" + { + "DisplayName" = "8:Release" + "IsDebugOnly" = "11:FALSE" + "IsReleaseOnly" = "11:TRUE" + "OutputFilename" = "8:Release\\authtokenclient_msm.msm" + "PackageFilesAs" = "3:2" + "PackageFileSize" = "3:-2147483648" + "CabType" = "3:1" + "Compression" = "3:2" + "SignOutput" = "11:FALSE" + "CertificateFile" = "8:" + "PrivateKeyFile" = "8:" + "TimeStampServer" = "8:" + "InstallerBootstrapper" = "3:1" + } + } + "Deployable" + { + "CustomAction" + { + } + "DefaultFeature" + { + "Name" = "8:DefaultFeature" + "Title" = "8:" + "Description" = "8:" + } + "File" + { + "{A582A373-4685-4296-BEFE-614B80A702C3}:_22FDEF26EDCE4831A621BB20C7EB4508" + { + "SourcePath" = "8:..\\..\\..\\include\\casa_c_authtoken.h" + "TargetName" = "8:casa_c_authtoken.h" + "Tag" = "8:" + "Folder" = "8:_9568FCF514C14B54BAB7D1D5D183D3C5" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{A582A373-4685-4296-BEFE-614B80A702C3}:_313DE095D13281AF91A64E3F3D472413" + { + "SourcePath" = "8:Secur32.dll" + "TargetName" = "8:Secur32.dll" + "Tag" = "8:" + "Folder" = "8:_F5F5F604B81645F8B6463F7A7D6A53AD" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:TRUE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } + "{A582A373-4685-4296-BEFE-614B80A702C3}:_643B8C25BBD34AD0B405B27E06E03698" + { + "SourcePath" = "8:..\\..\\..\\client\\mechanisms\\krb5\\windows\\Krb5Authenticate.conf" + "TargetName" = "8:Krb5Authenticate.conf" + "Tag" = "8:" + "Folder" = "8:_DEA051CA331E4FEA83D99711FB584664" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{A582A373-4685-4296-BEFE-614B80A702C3}:_92336612AC7D083F97ED302BB7674A2D" + { + "SourcePath" = "8:micasa.dll" + "TargetName" = "8:micasa.dll" + "Tag" = "8:" + "Folder" = "8:_F5F5F604B81645F8B6463F7A7D6A53AD" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:TRUE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } + "{A582A373-4685-4296-BEFE-614B80A702C3}:_9A3A0F1784E448538A42AE8722C1FE40" + { + "SourcePath" = "8:..\\..\\..\\client\\windows\\authtoken.lib" + "TargetName" = "8:authtoken.lib" + "Tag" = "8:" + "Folder" = "8:_01897726E7804A3B875B67A1C2692147" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{A582A373-4685-4296-BEFE-614B80A702C3}:_9AF33A7F4DD64BB58CD561EC8145A8A3" + { + "SourcePath" = "8:..\\..\\..\\include\\windows\\casa_c_authtoken_ex.h" + "TargetName" = "8:casa_c_authtoken_ex.h" + "Tag" = "8:" + "Folder" = "8:_9568FCF514C14B54BAB7D1D5D183D3C5" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{A582A373-4685-4296-BEFE-614B80A702C3}:_9C164F1F2FC0451CA2814BE9BAD532FB" + { + "SourcePath" = "8:..\\..\\..\\client\\client.conf" + "TargetName" = "8:client.conf" + "Tag" = "8:" + "Folder" = "8:_24DA90392089420889094EC07EB4F28C" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{A582A373-4685-4296-BEFE-614B80A702C3}:_B0715A326B76440C90A71D7BB2B61C52" + { + "SourcePath" = "8:..\\..\\..\\client\\mechanisms\\pwd\\windows\\PwdAuthenticate.conf" + "TargetName" = "8:PwdAuthenticate.conf" + "Tag" = "8:" + "Folder" = "8:_DEA051CA331E4FEA83D99711FB584664" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{A582A373-4685-4296-BEFE-614B80A702C3}:_E35F46E021184676375C6223ED1BDFCF" + { + "SourcePath" = "8:WINHTTP.dll" + "TargetName" = "8:WINHTTP.dll" + "Tag" = "8:" + "Folder" = "8:_F5F5F604B81645F8B6463F7A7D6A53AD" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:TRUE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } + } + "FileType" + { + } + "Folder" + { + "{B4CE2BB7-2D9F-4E14-A952-99DFEBF520A8}:_8E0BBDD021EA45308BD98380F28EB7F6" + { + "Name" = "8:#1927" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:GAC" + "Folders" + { + } + } + "{78BAF5CE-F2E5-45BE-83BC-DB6AF387E941}:_DB481DA18FE347988F44E459AD84EDE9" + { + "Name" = "8:#1912" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:ProgramFilesFolder" + "Folders" + { + "{F27BD5C5-A65D-4608-96D4-7C5DA1F76302}:_00A3E8736D134835AD0537E00F100987" + { + "Name" = "8:Novell" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_6F4D982C87CA4DF991766D49335B6669" + "Folders" + { + "{F27BD5C5-A65D-4608-96D4-7C5DA1F76302}:_7911DA52FBB24F3DB6BAF4B8BD9E57BF" + { + "Name" = "8:CASA" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_5C00DF0C10DE42D887AF2473050E45C9" + "Folders" + { + "{F27BD5C5-A65D-4608-96D4-7C5DA1F76302}:_01897726E7804A3B875B67A1C2692147" + { + "Name" = "8:lib" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_9CB2846430C044D4A85E07E79ED81EC6" + "Folders" + { + } + } + "{F27BD5C5-A65D-4608-96D4-7C5DA1F76302}:_9568FCF514C14B54BAB7D1D5D183D3C5" + { + "Name" = "8:include" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_E75CE2ED8E574BD6BDBF415E739623A2" + "Folders" + { + } + } + "{F27BD5C5-A65D-4608-96D4-7C5DA1F76302}:_B639068B7BE1480495ADAF8B2461A075" + { + "Name" = "8:etc" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_B04A2882FFAA4A959983F9D9750066CB" + "Folders" + { + "{F27BD5C5-A65D-4608-96D4-7C5DA1F76302}:_24DA90392089420889094EC07EB4F28C" + { + "Name" = "8:auth" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_AE09329FDCD54A98A0A90DDD67FE7E50" + "Folders" + { + "{F27BD5C5-A65D-4608-96D4-7C5DA1F76302}:_DEA051CA331E4FEA83D99711FB584664" + { + "Name" = "8:mechanisms" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_DA97A45985F64232A6DEAD78C88EDEE5" + "Folders" + { + } + } + } + } + } + } + } + } + } + } + } + } + "{78BAF5CE-F2E5-45BE-83BC-DB6AF387E941}:_E092F841E4D04920B053C3F6A5151BA2" + { + "Name" = "8:#1914" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:SystemFolder" + "Folders" + { + } + } + "{29CD8198-A6F0-4B93-8B90-AC03CFEAD328}:_F5F5F604B81645F8B6463F7A7D6A53AD" + { + "DefaultLocation" = "8:[ProgramFilesFolder]\\novell\\casa\\lib" + "DisplayName" = "8:Module Retargetable Folder" + "Description" = "8:" + "Name" = "8:Module Retargetable Folder" + "AlwaysCreate" = "11:TRUE" + "Condition" = "8:" + "Transitive" = "11:TRUE" + "Property" = "8:NEWRETARGETABLEPROPERTY1" + "Folders" + { + } + } + } + "Sequences" + { + } + "MergeModule" + { + "{35A69C6E-5BA4-440D-803D-762B59A45393}:_472FEAD17E7B45FF92E93D80B3379C47" + { + "UseDynamicProperties" = "11:FALSE" + "IsDependency" = "11:TRUE" + "SourcePath" = "8:dotnetfxredist_x86.msm" + "LanguageId" = "3:1033" + "Exclude" = "11:FALSE" + "Folder" = "8:" + "Feature" = "8:" + "IsolateTo" = "8:" + } + } + "Module" + { + "ModuleSignature" = "8:MergeModule.375AEECA1C3A4EC3AF37E3E5BE6711DD" + "Version" = "8:1.0.0.0" + "Title" = "8:authtokenclient_msm" + "Subject" = "8:" + "Author" = "8:Novell" + "Keywords" = "8:" + "Comments" = "8:" + "SearchPath" = "8:" + "UseSystemSearchPath" = "11:TRUE" + } + "ProjectOutput" + { + "{8062640A-2EEE-46E9-AB67-688E9A886E9F}:_191525A919DD46AD8D70B7735EE4F451" + { + "SourcePath" = "8:..\\..\\..\\client\\windows\\Debug\\authtoken.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_F5F5F604B81645F8B6463F7A7D6A53AD" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + "ProjectOutputGroupRegister" = "3:1" + "OutputConfiguration" = "8:" + "OutputGroupCanonicalName" = "8:Built" + "OutputProjectGuid" = "8:{7BD9A5DB-DE7D-40B7-A397-04182DC2F632}" + "ShowKeyOutput" = "11:FALSE" + "ExcludeFilters" + { + } + } + "{8062640A-2EEE-46E9-AB67-688E9A886E9F}:_3986DA1502244FFBB04A66472E74633B" + { + "SourcePath" = "8:..\\..\\..\\client\\mechanisms\\pwd\\windows\\Debug\\pwmech.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_F5F5F604B81645F8B6463F7A7D6A53AD" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + "ProjectOutputGroupRegister" = "3:1" + "OutputConfiguration" = "8:" + "OutputGroupCanonicalName" = "8:Built" + "OutputProjectGuid" = "8:{5499F624-F371-4559-B4C2-A484BCE892FD}" + "ShowKeyOutput" = "11:FALSE" + "ExcludeFilters" + { + } + } + "{8062640A-2EEE-46E9-AB67-688E9A886E9F}:_7A5EA42289F94648877FA695EB1853CE" + { + "SourcePath" = "8:..\\..\\..\\client\\mechanisms\\krb5\\windows\\Debug\\krb5mech.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_F5F5F604B81645F8B6463F7A7D6A53AD" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + "ProjectOutputGroupRegister" = "3:1" + "OutputConfiguration" = "8:" + "OutputGroupCanonicalName" = "8:Built" + "OutputProjectGuid" = "8:{5499F624-F371-4559-B4C2-A484BCE892FD}" + "ShowKeyOutput" = "11:FALSE" + "ExcludeFilters" + { + } + } + "{8062640A-2EEE-46E9-AB67-688E9A886E9F}:_8292EFFD84EF46C6BD2F1F3E20808684" + { + "SourcePath" = "8:..\\..\\..\\client\\csharp\\Novell.Casa.Authtoken\\obj\\Debug\\Novell.Casa.Client.Auth.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_8E0BBDD021EA45308BD98380F28EB7F6" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + "ProjectOutputGroupRegister" = "3:1" + "OutputConfiguration" = "8:" + "OutputGroupCanonicalName" = "8:Built" + "OutputProjectGuid" = "8:{1BA1FC97-5AF1-4506-A7FD-EBFD46D361A0}" + "ShowKeyOutput" = "11:TRUE" + "ExcludeFilters" + { + } + } + } + "Registry" + { + "HKLM" + { + "Keys" + { + } + } + "HKCU" + { + "Keys" + { + } + } + "HKCR" + { + "Keys" + { + } + } + "HKU" + { + "Keys" + { + } + } + "HKPU" + { + "Keys" + { + } + } + } + "Shortcut" + { + } + } +}