This branch was created to contain the "native" auth_token components.

This was required because autobuild restrictions are forcing us to build
the native components separate from the java components.
This commit is contained in:
Juan Carlos Luciani 2006-07-27 15:28:07 +00:00
parent d2a89a5f7a
commit b49318e38a
109 changed files with 24472 additions and 0 deletions

View File

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

View File

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

View File

View File

@ -0,0 +1,38 @@
#######################################################################
#
# Copyright (C) 2006 Novell, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# Author: Juan Carlos Luciani <jluciani@novell.com>
#
#######################################################################
SUBDIRS = server package
DIST_SUBDIRS = include server package
EXTRA_DIST = autogen.sh
.PHONY: package package-clean package-install package-uninstall
package package-clean package-install package-uninstall:
$(MAKE) -C package $@
clean-local:
if [ -d lib ]; then rm -rf lib; fi
maintainer-clean-local:
rm -f Makefile.in

View File

View File

@ -0,0 +1,90 @@
/***********************************************************************
*
* 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 indentity information contained in the
Identity Token as well as the type of Identity Token utilized depends on what is
configured for the tatget service.
Session Tokens and Authentication Tokens are signed by the issuing ATS using Signing
Certificates. Session Tokens and Authentication Tokens have a Lifetime Value associated
with them. Token verification involves verifying the token signatures, verifying that
the tokens where signed by a trusted entity, and verifying that the token lifetime has
not been exceeeded.
The auth_token client/service protocol allows for the authentication of the client entity.
auth_token relies in the server authentication mechanisms of SSL to verify the identity
of the ATS.
IMPLEMENTATION STRATEGY AND CURRENT STATUS
auth_token is currently under development and is not ready to be used in production.
The implementation strategy has been to first complete the framework with all of its
modules, APIs, and packaging to allow application writters to start developing to it.
Once this is done, then the implementation focus will switch to completing the plumbing.
As of this time, a lot of the framework has been completed and there are sample
applications that can be utilized to exercise it. For a more complete picture of where
we are, look at the various TODO lists present in the child folders.
The schedule for completing auth_token is agressive.
SECURITY CONSIDERATIONS
CASA Authentication Tokens when compromised can be used to either impersonate
a user or to obtain identity information about the user. Because of this it is
important that the tokens be secured by applications making use of them. It is
recommended that the tokens be transmitted using SSL.

View File

@ -0,0 +1,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
- Plug-in auth_token into the CASA make system.

View File

@ -0,0 +1,60 @@
Microsoft Visual Studio Solution File, Format Version 8.00
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "client", "client\client.vcproj", "{7BD9A5DB-DE7D-40B7-A397-04182DC2F632}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "client\test\test.vcproj", "{6034EBF1-0838-45C4-A538-A41A31EC8F46}"
ProjectSection(ProjectDependencies) = postProject
{7BD9A5DB-DE7D-40B7-A397-04182DC2F632} = {7BD9A5DB-DE7D-40B7-A397-04182DC2F632}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "krb5", "client\mechanisms\krb5\krb5.vcproj", "{5499F624-F371-4559-B4C2-A484BCE892FD}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pwd", "client\mechanisms\pwd\pwd.vcproj", "{5499F624-F371-4559-B4C2-A484BCE892FD}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "authtokenclient_msm", "client\authtokenclient_msm\authtokenclient_msm.vdproj", "{70ED319E-F496-4F07-878C-1921426DD399}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "authtokenclient_msi", "client\authtokenclient_msi\authtokenclient_msi.vdproj", "{AA014EB3-8AD3-49B8-92E3-F8AA0FBCEE9B}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
Release = Release
EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution
{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
{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
{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
{70ED319E-F496-4F07-878C-1921426DD399}.Debug.ActiveCfg = Debug
{70ED319E-F496-4F07-878C-1921426DD399}.Debug.Build.0 = Debug
{70ED319E-F496-4F07-878C-1921426DD399}.Release.ActiveCfg = Release
{70ED319E-F496-4F07-878C-1921426DD399}.Release.Build.0 = Release
{AA014EB3-8AD3-49B8-92E3-F8AA0FBCEE9B}.Debug.ActiveCfg = Debug
{AA014EB3-8AD3-49B8-92E3-F8AA0FBCEE9B}.Release.ActiveCfg = Release
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
GlobalSection(ExtensibilityAddIns) = postSolution
EndGlobalSection
EndGlobal

130
CASA-auth-token/native/autogen.sh Executable file
View File

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

View File

@ -0,0 +1,67 @@
/***********************************************************************
*
* 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/opt/novell/CASA/authtoken.d/modules.d.
The path to this folder under Windows is \Program Files\novell\CASA\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.

View File

@ -0,0 +1,18 @@
/***********************************************************************
*
* TODO for libcasa_c_authtoken
*
***********************************************************************/
INTRODUCTION
This file contains a list of the items still outstanding for libcasa_c_authtoken.
OUTSTANDING ITEMS
- Implementation of Linux specific code.
- Re-structure the token cache to differentiate between Session Tokens and Authentication Tokens.
- Use the CASA cache as the token store.
- Switch Client/Server protocol to use SOAP Messages.
- Enable communications over HTTPS instead of over HTTP.

View File

@ -0,0 +1,339 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
//===[ 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,
INOUT char **ppAuthToken)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// L2
//=======================================================================--
{
CasaStatus retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_UNSUCCESSFUL);
AuthTokenIf *pAuthTokenIf;
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,
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,
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;
}
//++=======================================================================
//++=======================================================================
//++=======================================================================

View File

@ -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 <jluciani@novell.com>
*
***********************************************************************/
//===[ 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:
*
* <?xml version="1.0" encoding="ISO-8859-1"?>
* <auth_req>
* <realm>realm value</realm>
* <mechanism>mechanism id value</mechanism>
* <auth_mech_token>authentication mechanism token data</auth_mech_token>
* </auth_req>
*
*/
// 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 // </
+ strlen(REALM_ELEMENT_NAME)
+ 3 // >crlf
+ 1 // <
+ strlen(MECHANISM_ELEMENT_NAME)
+ 1 // >
+ strlen(pAuthContext->pMechanism)
+ 2 // </
+ strlen(MECHANISM_ELEMENT_NAME)
+ 3 // >crlf
+ 1 // <
+ strlen(AUTH_MECH_TOKEN_ELEMENT_NAME)
+ 1 // >
+ strlen(pAuthMechToken)
+ 2 // </
+ strlen(AUTH_MECH_TOKEN_ELEMENT_NAME)
+ 3 // >crlf
+ 2 // </
+ strlen(AUTH_REQUEST_ELEMENT_NAME)
+ 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, "</");
strcat(pMsg, REALM_ELEMENT_NAME);
strcat(pMsg, ">\r\n");
strcat(pMsg, "<");
strcat(pMsg, MECHANISM_ELEMENT_NAME);
strcat(pMsg, ">");
strcat(pMsg, pAuthContext->pMechanism);
strcat(pMsg, "</");
strcat(pMsg, MECHANISM_ELEMENT_NAME);
strcat(pMsg, ">\r\n");
strcat(pMsg, "<");
strcat(pMsg, AUTH_MECH_TOKEN_ELEMENT_NAME);
strcat(pMsg, ">");
strcat(pMsg, pAuthMechToken);
strcat(pMsg, "</");
strcat(pMsg, AUTH_MECH_TOKEN_ELEMENT_NAME);
strcat(pMsg, ">\r\n");
strcat(pMsg, "</");
strcat(pMsg, AUTH_REQUEST_ELEMENT_NAME);
strcat(pMsg, ">");
}
else
{
DbgTrace(0, "-BuildAuthenticateMsg- Buffer allocation error\n", 0);
}
DbgTrace(1, "-BuildAuthenticateMsg- End, pMsg = %08X\n", 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:
*
* <?xml version="1.0" encoding="ISO-8859-1"?>
* <auth_resp>
* <status><description>ok</description>200</status>
* <session_token><lifetime>lifetime value</lifetime>session token data</session_token>
* </auth_resp>
*
* 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:
*
* <?xml version="1.0" encoding="ISO-8859-1"?>
* <auth_resp>
* <status><description>status description</description>status code</status>
* </auth_resp>
*
* Plase note that the protocol utilizes the status codes defined
* in the HTTP 1.1 Specification.
*
*/
// 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,
AuthRespStartElementHandler,
AuthRespEndElementHandler);
// Set the character data handler
XML_SetCharacterDataHandler(p, 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);
}
//++=======================================================================
//++=======================================================================
//++=======================================================================

View File

@ -0,0 +1,801 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
//===[ 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:
// 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:
// 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:
// 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:
*
* <?xml version="1.0" encoding="ISO-8859-1"?>
* <auth_policy>
* <auth_source>
* <realm>realm name</realm>
* <mechanism>authentication mechanism type</mechanism>
* <mechanism_info>authentication mechanism context data</mechanism_info>
* </auth_source>
* ...
* </auth_policy>
*
* 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 following is a sample authentication policy document:
*
* <?xml version="1.0" encoding="ISO-8859-1"?>
* <auth_policy>
* <auth_source>
* <realm>Corp_eDirTree</realm>
* <mechanism>Krb5Authenticate</mechanism>
* <mechanism_info>host/hostname</mechanism_info>
* </auth_source>
* <auth_source>
* <realm>Corp_eDirTree</realm>
* <mechanism>PwdAuthenticate</mechanism>
* <mechanism_info></mechanism_info>
* </auth_source>
* </auth_policy>
*
* 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,
&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,
AuthPolicyStartElementHandler,
AuthPolicyEndElementHandler);
// Set the character data handler
XML_SetCharacterDataHandler(p, 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);
}
//++=======================================================================
//++=======================================================================
//++=======================================================================

View File

@ -0,0 +1,694 @@
"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:_C9C2CAF6FE7A41938101D843D18673B7"
"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"
{
}
}
"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:{197B9AC3-1D6A-4EA8-AC8A-C7695F57A28F}"
"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:<VsdDialogDir>\\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:<VsdDialogDir>\\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:<VsdDialogDir>\\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:<VsdDialogDir>\\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:<VsdDialogDir>\\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:<VsdDialogDir>\\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:<VsdDialogDir>\\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:<VsdDialogDir>\\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}:_7F0506CDE05C426E9A69E1F0F6A1B9A4"
{
"Sequence" = "3:200"
"DisplayName" = "8:Installation Folder"
"UseDynamicProperties" = "11:TRUE"
"IsDependency" = "11:FALSE"
"SourcePath" = "8:<VsdDialogDir>\\VsdFolderDlg.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}:_E227037047AF41C394E3138699F6DD62"
{
"Sequence" = "3:300"
"DisplayName" = "8:Confirm Installation"
"UseDynamicProperties" = "11:TRUE"
"IsDependency" = "11:FALSE"
"SourcePath" = "8:<VsdDialogDir>\\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:<VsdDialogDir>\\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:<VsdDialogDir>\\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"
{
}
"ProjectOutput"
{
"{8062640A-2EEE-46E9-AB67-688E9A886E9F}:_C9C2CAF6FE7A41938101D843D18673B7"
{
"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:{70ED319E-F496-4F07-878C-1921426DD399}"
"ShowKeyOutput" = "11:TRUE"
"ExcludeFilters"
{
}
"KeyOutputModule"
{
"UseDynamicProperties" = "11:TRUE"
"IsDependency" = "11:FALSE"
"SourcePath" = "8:..\\authtokenclient_msm\\Release\\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"
{
}
}
}

View File

@ -0,0 +1,542 @@
"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:_0C000CB7C5FA4E2BB6A6CB1C204EABA6"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_0C0B5ECE6E9C47F1A1F13B58141B5DC8"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_1231718055D14020BF756DCF44D2BF22"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_313DE095D13281AF91A64E3F3D472413"
"OwnerKey" = "8:_DB9D7F0710B44F858325E4EFCCB2EEB3"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_677B016062384F4C8A73EC952CBCFD76"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_753EBE1EB0DC420C88ED02E5A978FF35"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_767D1F0838D74B6C86C5E9C14643AE48"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_92336612AC7D083F97ED302BB7674A2D"
"OwnerKey" = "8:_9A2FC85FE99C48E8AD1E4813BE33A03A"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_9A2FC85FE99C48E8AD1E4813BE33A03A"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_DB9D7F0710B44F858325E4EFCCB2EEB3"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_FE85A5D48B5A23F3077871E9FD2378DE"
"OwnerKey" = "8:_0C0B5ECE6E9C47F1A1F13B58141B5DC8"
"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}:_0C000CB7C5FA4E2BB6A6CB1C204EABA6"
{
"SourcePath" = "8:..\\mechanisms\\pwd\\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}:_1231718055D14020BF756DCF44D2BF22"
{
"SourcePath" = "8:..\\mechanisms\\krb5\\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}:_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:FALSE"
"IsDependency" = "11:TRUE"
"IsolateTo" = "8:"
}
"{A582A373-4685-4296-BEFE-614B80A702C3}:_677B016062384F4C8A73EC952CBCFD76"
{
"SourcePath" = "8:..\\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}:_753EBE1EB0DC420C88ED02E5A978FF35"
{
"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}:_767D1F0838D74B6C86C5E9C14643AE48"
{
"SourcePath" = "8:..\\..\\..\\include\\casa_status.h"
"TargetName" = "8:casa_status.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}:_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:FALSE"
"IsDependency" = "11:TRUE"
"IsolateTo" = "8:"
}
"{A582A373-4685-4296-BEFE-614B80A702C3}:_FE85A5D48B5A23F3077871E9FD2378DE"
{
"SourcePath" = "8:WINHTTP.dll"
"TargetName" = "8:WINHTTP.dll"
"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:TRUE"
"IsDependency" = "11:TRUE"
"IsolateTo" = "8:"
}
}
"FileType"
{
}
"Folder"
{
"{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"
{
}
}
}
}
}
}
}
}
}
}
}
}
"{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"
{
}
"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}:_0C0B5ECE6E9C47F1A1F13B58141B5DC8"
{
"SourcePath" = "8:..\\windows\\Debug\\authtoken.dll"
"TargetName" = "8:"
"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:"
"ProjectOutputGroupRegister" = "3:1"
"OutputConfiguration" = "8:"
"OutputGroupCanonicalName" = "8:Built"
"OutputProjectGuid" = "8:{7BD9A5DB-DE7D-40B7-A397-04182DC2F632}"
"ShowKeyOutput" = "11:FALSE"
"ExcludeFilters"
{
}
}
"{8062640A-2EEE-46E9-AB67-688E9A886E9F}:_9A2FC85FE99C48E8AD1E4813BE33A03A"
{
"SourcePath" = "8:..\\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}:_DB9D7F0710B44F858325E4EFCCB2EEB3"
{
"SourcePath" = "8:..\\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"
{
}
}
}
"Registry"
{
"HKLM"
{
"Keys"
{
}
}
"HKCU"
{
"Keys"
{
}
}
"HKCR"
{
"Keys"
{
}
}
"HKU"
{
"Keys"
{
}
}
"HKPU"
{
"Keys"
{
}
}
}
"Shortcut"
{
}
}
}

View File

@ -0,0 +1,209 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="client"
ProjectGUID="{7BD9A5DB-DE7D-40B7-A397-04182DC2F632}"
RootNamespace="client"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)client\windows\$(ConfigurationName)"
IntermediateDirectory="$(SolutionDir)client\windows\$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/D &quot;XML_STATIC&quot;"
Optimization="0"
AdditionalIncludeDirectories=".;windows;..\include;..\..\include;..\..\..\Expat-2.0.0\source\lib"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
IgnoreImportLibrary="FALSE"
AdditionalOptions="/EXPORT:ObtainAuthToken"
AdditionalDependencies="ws2_32.lib winhttp.lib libexpatml.lib"
OutputFile="$(OutDir)/authtoken.dll"
LinkIncremental="1"
AdditionalLibraryDirectories="&quot;..\..\..\Expat-2.0.0\StaticLibs&quot;"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/client.pdb"
SubSystem="0"
ImportLibrary="$(SolutionDir)client\windows/$(TargetName).lib"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"
CommandLine="mkdir \&quot;Program Files&quot;\novell\
mkdir \&quot;Program Files&quot;\novell\casa
mkdir \&quot;Program Files&quot;\novell\casa\lib\
copy $(OutDir)\authtoken.dll \&quot;Program Files&quot;\novell\casa\lib\authtoken.dll
copy $(SolutionDir)client\windows\authtoken.lib \&quot;Program Files&quot;\novell\casa\lib\authtoken.lib
"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)client\windows\$(ConfigurationName)"
IntermediateDirectory="$(SolutionDir)client\windows\$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/D &quot;XML_STATIC&quot;"
AdditionalIncludeDirectories=".;windows;..\include;..\..\include;..\..\..\Expat-2.0.0\source\lib"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="4"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/EXPORT:ObtainAuthToken"
AdditionalDependencies="ws2_32.lib winhttp.lib libexpatml.lib"
OutputFile="$(OutDir)/authtoken.dll"
LinkIncremental="1"
AdditionalLibraryDirectories="&quot;..\..\..\Expat-2.0.0\StaticLibs&quot;"
GenerateDebugInformation="TRUE"
SubSystem="0"
OptimizeReferences="2"
EnableCOMDATFolding="2"
ImportLibrary="$(SolutionDir)client\windows\$(TargetName).lib"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"
CommandLine="mkdir \&quot;Program Files&quot;\novell\
mkdir \&quot;Program Files&quot;\novell\casa
mkdir \&quot;Program Files&quot;\novell\casa\lib\
copy $(OutDir)\authtoken.dll \&quot;Program Files&quot;\novell\casa\lib\authtoken.dll
copy $(SolutionDir)client\windows\authtoken.lib \&quot;Program Files&quot;\novell\casa\lib\authtoken.lib
"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath=".\authmech.c">
</File>
<File
RelativePath=".\authmsg.c">
</File>
<File
RelativePath=".\authpolicy.c">
</File>
<File
RelativePath=".\win32\authtoken.def">
</File>
<File
RelativePath=".\windows\cache.c">
</File>
<File
RelativePath=".\config.c">
</File>
<File
RelativePath=".\windows\dllsup.c">
</File>
<File
RelativePath=".\engine.c">
</File>
<File
RelativePath=".\getpolicymsg.c">
</File>
<File
RelativePath=".\gettokenmsg.c">
</File>
<File
RelativePath=".\windows\platform.c">
</File>
<File
RelativePath=".\windows\rpc.c">
</File>
<File
RelativePath=".\util.c">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
<File
RelativePath=".\internal.h">
</File>
<File
RelativePath="..\include\list_entry.h">
</File>
<File
RelativePath=".\mech_if.h">
</File>
<File
RelativePath=".\windows\platform.h">
</File>
<File
RelativePath="..\include\proto.h">
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,685 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
//===[ 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(1, "-GetConfigInterface- Unable to open config file, errno = %d\n", errno);
}
}
else
{
DbgTrace(0, "-GetConfigInterface- Buffer allocation error\n", 0);
}
}
DbgTrace(2, "-GetConfigInterface- End, retStatus = %08X\n", retStatus);
return retStatus;
}
//++=======================================================================
//++=======================================================================
//++=======================================================================

View File

@ -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 <jluciani@novell.com>
*
***********************************************************************/
#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_

View File

@ -0,0 +1,663 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
//===[ Include files ]=====================================================
#include "internal.h"
//===[ Type definitions ]==================================================
#define DEFAULT_RETRY_LIFETIME 5 // seconds
//===[ Function prototypes ]===============================================
//===[ Global variables ]==================================================
//
// Debug tracing level
//
int DebugLevel = 0;
//
// Operating parameter
//
bool secureRpcSetting = false;
int retryLifetime = DEFAULT_RETRY_LIFETIME;
//++=======================================================================
static
CasaStatus
ObtainSessionToken(
IN RpcSession *pRpcSession,
IN AuthPolicy *pAuthPolicy,
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);
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
{
// Release auth cache entry reference
ReleaseAuthCacheEntry(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);
if (pCacheEntry == NULL)
{
// Get authentication mechanism token
retStatus = GetAuthMechToken(pAuthContext, &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;
}
// Create a cache entry for the auth context
pCacheEntry = CreateSessionTokenCacheEntry(pAuthContext->pContext);
if (pCacheEntry)
{
char *pReqMsg = NULL;
char *pRespMsg = NULL;
int respLen;
int cacheEntryLifetime = retryLifetime; // Initialize to retry in case of failure
// Authenticate to the ATS
pReqMsg = BuildAuthenticateMsg(pAuthContext, pAuthMechToken);
if (pReqMsg)
{
// Issue rpc
retStatus = Rpc(pRpcSession,
"Authenticate",
secureRpcSetting,
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->pToken = pAuthenticateResp->pToken;
pAuthenticateResp->pToken = NULL; // To keep us from freeing the buffer
cacheEntryLifetime = pAuthenticateResp->tokenLifetime;
// 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 (CASA_SUCCESS(retStatus)
|| CasaStatusCode(retStatus) == CASA_STATUS_AUTH_SERVER_UNAVAILABLE)
{
pCacheEntry->status = retStatus;
AddEntryToAuthCache(pCacheEntry, cacheEntryLifetime);
}
// Release the cache entry if the resulting status is not successful
if (!CASA_SUCCESS(retStatus))
{
// Release auth cache entry reference
ReleaseAuthCacheEntry(pCacheEntry);
}
}
else
{
DbgTrace(0, "-ObtainSessionToken- Cache entry creation failure\n", 0);
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_INSUFFICIENT_RESOURCES);
}
// Free up the buffer associated with the authentication mechanism token
free(pAuthMechToken);
}
else
{
// Release auth cache entry reference
ReleaseAuthCacheEntry(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->pToken) + 1);
if (*ppSessionToken)
{
// Copy the token onto the allocated buffer
strcpy(*ppSessionToken, pCacheEntry->pToken);
}
else
{
DbgTrace(0, "-ObtainSessionToken- Buffer allocation failure\n", 0);
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_INSUFFICIENT_RESOURCES);
}
// Release auth cache entry reference
ReleaseAuthCacheEntry(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)
//
// 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(pHostName);
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, pHostName);
if (pReqMsg)
{
// Issue rpc
retStatus = Rpc(pRpcSession,
"GetAuthPolicy",
secureRpcSetting,
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, &pSessionToken);
if (CASA_SUCCESS(retStatus))
{
// Request auth token for the service
free(pReqMsg);
pReqMsg = BuildGetAuthTokenMsg(pServiceName, pHostName, pSessionToken);
if (pReqMsg)
{
// Free the previous response msg buffer
free(pRespMsg);
pRespMsg = NULL;
// Issue rpc
retStatus = Rpc(pRpcSession,
"GetAuthToken",
secureRpcSetting,
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 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 = CASA_STATUS_SUCCESS;
AuthCacheEntry *pCacheEntry;
char *pNormalizedHostName;
DbgTrace(1, "-ObtainAuthToken- Start\n", 0);
// Verify the input parameters
if (pServiceName == NULL
|| pHostName == NULL
|| pAuthTokenBufLen == NULL
|| (*pAuthTokenBufLen != 0 && pAuthTokenBuf == NULL))
{
DbgTrace(0, "-ObtainAuthToken- Invalid parameter\n", 0);
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_INVALID_PARAMETER);
goto exit;
}
// Normalize the host name
pNormalizedHostName = NormalizeHostName(pHostName);
if (pNormalizedHostName)
{
// Start user process synchronization
AcquireUserMutex();
// Try to find a cache entry for the service
pCacheEntry = FindAuthTokenEntryInCache(pServiceName, pNormalizedHostName);
if (pCacheEntry == NULL)
{
// No entry found in the cache, create one.
pCacheEntry = CreateAuthTokenCacheEntry(pServiceName, pNormalizedHostName);
if (pCacheEntry)
{
int cacheEntryLifetime = retryLifetime; // Initialize to retry in case of failure
// Cache entry created, now try to obtain auth token from the CASA Server
retStatus = ObtainAuthTokenFromServer(pServiceName,
pNormalizedHostName,
&pCacheEntry->pToken,
&cacheEntryLifetime);
// 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->status = retStatus;
AddEntryToAuthCache(pCacheEntry, cacheEntryLifetime);
}
// Release the cache entry if the resulting status is not successful
if (!CASA_SUCCESS(retStatus))
{
// Release auth cache entry reference
ReleaseAuthCacheEntry(pCacheEntry);
}
}
else
{
DbgTrace(0, "-ObtainAuthToken- Cache entry creation failure\n", 0);
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_INSUFFICIENT_RESOURCES);
}
}
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))
{
// Release auth cache entry reference
ReleaseAuthCacheEntry(pCacheEntry);
}
}
// Try to return auth token if we have one to return
if (CASA_SUCCESS(retStatus))
{
int tokenLen = (int) strlen(pCacheEntry->pToken) + 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
strcpy(pAuthTokenBuf, pCacheEntry->pToken);
}
else
{
DbgTrace(0, "-ObtainAuthToken- 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;
// Release auth cache entry reference
ReleaseAuthCacheEntry(pCacheEntry);
}
// Stop user process synchronization
ReleaseUserMutex();
// Free the space allocated for the normalized host name
free(pNormalizedHostName);
}
else
{
DbgTrace(0, "-ObtainAuthToken- Host name normalization failed\n", 0);
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_UNSUCCESSFUL);
}
exit:
DbgTrace(1, "-ObtainAuthToken- End, retStatus = %08X\n", retStatus);
return retStatus;
}
//++=======================================================================
int
InitializeLibrary(void)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// L2
//=======================================================================--
{
int retStatus = -1;
DbgTrace(1, "-InitializeLibrary- Start\n", 0);
// Create user synchronization mutex
if (CreateUserMutex() == 0)
{
// Initialize the auth cache
if (CASA_SUCCESS(InitializeAuthCache()))
{
// Initialize the host name normalization
if (CASA_SUCCESS(InitializeHostNameNormalization()))
{
// Success
retStatus = 0;
}
else
{
DbgTrace(0, "-InitializeLibrary- Error initializing host name normalization\n", 0);
}
}
else
{
DbgTrace(0, "-InitializeLibrary- Error initializing the auth cache\n", 0);
}
}
else
{
DbgTrace(0, "-InitializeLibrary- Error creating mutex for the user\n", 0);
}
DbgTrace(1, "-InitializeLibrary- End, retStatus = %08X\n", retStatus);
return retStatus;
}
//++=======================================================================
//++=======================================================================
//++=======================================================================

View File

@ -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 <jluciani@novell.com>
*
***********************************************************************/
//===[ 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 char *pServiceName,
IN 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:
*
* <?xml version="1.0" encoding="ISO-8859-1"?>
* <get_auth_policy_req>
* <service>service name<\service>
* <host>host name</host>
* </get_auth_policy_req>
*
*/
// 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 // </
+ strlen(SERVICE_ELEMENT_NAME)
+ 3 // >crlf
+ 2 // </
+ strlen(HOST_ELEMENT_NAME)
+ 1 // >
+ strlen(pHostName)
+ 2 // </
+ strlen(HOST_ELEMENT_NAME)
+ 3 // >crlf
+ 2 // </
+ strlen(GET_AUTH_POLICY_REQUEST_ELEMENT_NAME)
+ 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, "</");
strcat(pMsg, SERVICE_ELEMENT_NAME);
strcat(pMsg, ">\r\n");
strcat(pMsg, "<");
strcat(pMsg, HOST_ELEMENT_NAME);
strcat(pMsg, ">");
strcat(pMsg, pHostName);
strcat(pMsg, "</");
strcat(pMsg, HOST_ELEMENT_NAME);
strcat(pMsg, ">\r\n");
strcat(pMsg, "</");
strcat(pMsg, GET_AUTH_POLICY_REQUEST_ELEMENT_NAME);
strcat(pMsg, ">");
}
else
{
DbgTrace(0, "-BuildGetAuthPolicyMsg- Buffer allocation error\n", 0);
}
DbgTrace(1, "-BuildGetAuthPolicyMsg- End, pMsg = %08X\n", 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:
*
* <?xml version="1.0" encoding="ISO-8859-1"?>
* <get_auth_policy_resp>
* <status><description>ok</description>200</status>
* <auth_policy>authentication policy data</auth_policy>
* </get_auth_policy_resp>
*
* 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:
*
* <?xml version="1.0" encoding="ISO-8859-1"?>
* <get_auth_policy_resp>
* <status><description>status description</description>status code</status>
* </get_auth_policy_resp>
*
* Plase note that the protocol utilizes the status codes defined
* in the HTTP 1.1 Specification.
*
*/
// 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,
GetAuthPolicyRespStartElementHandler,
GetAuthPolicyRespEndElementHandler);
// Set the character data handler
XML_SetCharacterDataHandler(p, 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);
}
//++=======================================================================
//++=======================================================================
//++=======================================================================

View File

@ -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 <jluciani@novell.com>
*
***********************************************************************/
//===[ 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 char *pServiceName,
IN 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:
*
* <?xml version="1.0" encoding="ISO-8859-1"?>
* <get_auth_token_req>
* <service>service name</service>
* <host>host name</host>
* <session_token>session token data</session_token>
* </get_auth_token_req>
*
*/
// 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 // </
+ strlen(SERVICE_ELEMENT_NAME)
+ 3 // >crlf
+ 1 // <
+ strlen(HOST_ELEMENT_NAME)
+ 1 // >
+ strlen(pHostName)
+ 2 // </
+ strlen(HOST_ELEMENT_NAME)
+ 3 // >crlf
+ 1 // <
+ strlen(SESSION_TOKEN_ELEMENT_NAME)
+ 1 // >
+ strlen(pSessionToken)
+ 2 // </
+ strlen(SESSION_TOKEN_ELEMENT_NAME)
+ 3 // >crlf
+ 2 // </
+ strlen(GET_AUTH_TOKEN_REQUEST_ELEMENT_NAME)
+ 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, "</");
strcat(pMsg, SERVICE_ELEMENT_NAME);
strcat(pMsg, ">\r\n");
strcat(pMsg, "<");
strcat(pMsg, HOST_ELEMENT_NAME);
strcat(pMsg, ">");
strcat(pMsg, pHostName);
strcat(pMsg, "</");
strcat(pMsg, HOST_ELEMENT_NAME);
strcat(pMsg, ">\r\n");
strcat(pMsg, "<");
strcat(pMsg, SESSION_TOKEN_ELEMENT_NAME);
strcat(pMsg, ">");
strcat(pMsg, pSessionToken);
strcat(pMsg, "</");
strcat(pMsg, SESSION_TOKEN_ELEMENT_NAME);
strcat(pMsg, ">\r\n");
strcat(pMsg, "</");
strcat(pMsg, GET_AUTH_TOKEN_REQUEST_ELEMENT_NAME);
strcat(pMsg, ">");
}
else
{
DbgTrace(0, "-BuildGetAuthTokenMsg- Buffer allocation error\n", 0);
}
DbgTrace(1, "-BuildGetAuthTokenMsg- End, pMsg = %08X\n", 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:
*
* <?xml version="1.0" encoding="ISO-8859-1"?>
* <get_auth_token_resp>
* <status><description>ok</description>200</status>
* <auth_token><lifetime>lifetime value</lifetime>session token data</auth_token>
* </get_auth_token_resp>
*
* 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:
*
* <?xml version="1.0" encoding="ISO-8859-1"?>
* <get_auth_token_resp>
* <status><description>status description</description>status code</status>
* </get_auth_token_resp>
*
* 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,
GetAuthTokenRespStartElementHandler,
GetAuthTokenRespEndElementHandler);
// Set the character data handler
XML_SetCharacterDataHandler(p, 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);
}
//++=======================================================================
//++=======================================================================
//++=======================================================================

View File

@ -0,0 +1,369 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
#ifndef _INTERNAL_H_
#define _INTERNAL_H_
//===[ Include files ]=====================================================
#include "platform.h"
#include <expat.h>
#include <micasa_types.h>
#include <casa_status.h>
#include <casa_c_authtoken.h>
#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;
//===[ Inlines functions ]===============================================
//===[ Function prototypes ]===============================================
//===[ Global variables ]==================================================
//===[ Global externals ]==================================================
extern int DebugLevel;
extern char mechConfigFolder[];
extern char pathCharString[];
//===[ External prototypes ]===============================================
//
// Functions exported by engine.c
//
extern
int
InitializeLibrary(void);
//
// Functions exported by authmech.c
//
extern
CasaStatus
GetAuthMechToken(
IN AuthContext *pAuthContext,
INOUT char **ppAuthMechToken);
//
// Functions exported by getpolicymsg.c
//
extern
char*
BuildGetAuthPolicyMsg(
IN char *pServiceName,
IN 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 char *pServiceName,
IN 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);
extern
AuthCacheEntry*
CreateAuthTokenCacheEntry(
IN const char *pCacheKey,
IN const char *pGroupOrHostName);
extern
void
ReleaseAuthCacheEntry(
IN AuthCacheEntry *pEntry);
extern void
IncAuthCacheEntryRefCount(
IN AuthCacheEntry *pEntry);
extern
AuthCacheEntry*
FindSessionTokenEntryInCache(
IN const char *pCacheKey);
extern
AuthCacheEntry*
FindAuthTokenEntryInCache(
IN const char *pCacheKey,
IN const char *pGroupOrHostName);
extern
void
AddEntryToAuthCache(
IN AuthCacheEntry *pEntry,
IN int entryLifetime);
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(void);
extern
void
AcquireUserMutex(void);
extern
void
ReleaseUserMutex(void);
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 char *pHostName);
extern
void
CloseRpcSession(
IN RpcSession *pSession);
extern
CasaStatus
Rpc(
IN RpcSession *pSession,
IN char *pMethod,
IN bool secure,
IN char *pRequestData,
INOUT char **ppResponseData,
INOUT int *pResponseDataLen);
//
// 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);
extern
int
dtoul(
IN const char *cp,
IN const int len);
//=========================================================================
#endif // _INTERNAL_H_

View File

@ -0,0 +1,177 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
#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,
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.
//
// 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_

View File

@ -0,0 +1,12 @@
#######################################################
# #
# CASA Authentication Token System configuration file #
# for module: #
# #
# Krb5Authenticate #
# #
#######################################################
LibraryName \Program Files\novell\casa\lib\krb5mech.dll

View File

@ -0,0 +1,30 @@
/***********************************************************************
*
* 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.

View File

@ -0,0 +1,14 @@
/***********************************************************************
*
* TODO for krb5mech
*
***********************************************************************/
INTRODUCTION
This file contains a list of the items still outstanding for krb5mech.
OUTSTANDING ITEMS
- Implementation of Linux specific code.

View File

@ -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 <jluciani@novell.com>
*
***********************************************************************/
//===[ 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;
}
//++=======================================================================
//++=======================================================================
//++=======================================================================

View File

@ -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 <jluciani@novell.com>
*
***********************************************************************/
#ifndef _INTERNAL_H_
#define _INTERNAL_H_
//===[ Include files ]=====================================================
#include "platform.h"
#include <micasa_types.h>
#include <casa_status.h>
#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,
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_

View File

@ -0,0 +1,182 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="krb5"
ProjectGUID="{5499F624-F371-4559-B4C2-A484BCE892FD}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)client\mechanisms\krb5\windows\$(ConfigurationName)"
IntermediateDirectory="$(SolutionDir)client\mechanisms\krb5\windows\$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="-DSECURITY_WIN32"
Optimization="0"
AdditionalIncludeDirectories="windows;.;..\..;..\..\..\..\include"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/EXPORT:GetAuthTokenInterface"
AdditionalDependencies="secur32.lib"
OutputFile="$(OutDir)/krb5mech.dll"
LinkIncremental="1"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/pw.pdb"
SubSystem="0"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"
CommandLine="mkdir \&quot;Program Files&quot;\novell\
mkdir \&quot;Program Files&quot;\novell\casa
mkdir \&quot;Program Files&quot;\novell\casa\lib\
mkdir \&quot;Program Files&quot;\novell\casa\etc\
mkdir \&quot;Program Files&quot;\novell\casa\etc\auth\
mkdir \&quot;Program Files&quot;\novell\casa\etc\auth\mechanisms\
copy Krb5Authenticate.conf \&quot;Program Files&quot;\novell\casa\etc\auth\mechanisms\Krb5Authenticate.conf
copy $(OutDir)\krb5mech.dll \&quot;Program Files&quot;\novell\casa\lib\krb5mech.dll
"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)client\mechanisms\krb5\windows\$(ConfigurationName)"
IntermediateDirectory="$(SolutionDir)client\mechanisms\krb5\windows\$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="-DSECURITY_WIN32"
AdditionalIncludeDirectories="windows;.;..\..;..\..\..\..\include"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
RuntimeLibrary="4"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/EXPORT:GetAuthTokenInterface"
AdditionalDependencies="secur32.lib"
OutputFile="$(OutDir)/krb5mech.dll"
LinkIncremental="1"
GenerateDebugInformation="TRUE"
SubSystem="0"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"
CommandLine="mkdir \&quot;Program Files&quot;\novell\
mkdir \&quot;Program Files&quot;\novell\casa
mkdir \&quot;Program Files&quot;\novell\casa\lib\
mkdir \&quot;Program Files&quot;\novell\casa\etc\
mkdir \&quot;Program Files&quot;\novell\casa\etc\auth\
mkdir \&quot;Program Files&quot;\novell\casa\etc\auth\mechanisms\
copy Krb5Authenticate.conf \&quot;Program Files&quot;\novell\casa\etc\auth\mechanisms\Krb5Authenticate.conf
copy $(OutDir)\krb5mech.dll \&quot;Program Files&quot;\novell\casa\lib\krb5mech.dll
"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath=".\windows\dllsup.c">
</File>
<File
RelativePath=".\windows\get.c">
</File>
<File
RelativePath=".\interface.c">
</File>
<File
RelativePath=".\Krb5Authenticate.conf">
</File>
<File
RelativePath=".\win32\krb5mech.def">
</File>
<File
RelativePath=".\windows\platform.c">
</File>
<File
RelativePath=".\util.c">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
<File
RelativePath=".\internal.h">
</File>
<File
RelativePath=".\windows\platform.h">
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,282 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
//===[ 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;
}
//++=======================================================================
//++=======================================================================
//++=======================================================================

View File

@ -0,0 +1,132 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
//===[ 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);
}
//=========================================================================
//=========================================================================

View File

@ -0,0 +1,272 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
//===[ 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,
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.
//
// 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
|| pMechInfo == 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;
}
// 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:
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;
}
//++=======================================================================
//++=======================================================================
//++=======================================================================

View File

@ -0,0 +1,10 @@
LIBRARY KRB5MECH
DESCRIPTION 'CASA Kerberos V Authentication Mechanism Library.'
EXPORTS
; DllRegisterServer PRIVATE
; DllUnregisterServer PRIVATE
; DllGetClassObject PRIVATE
GetAuthTokenInterface PRIVATE
; DllCanUnloadNow PRIVATE

View File

@ -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 <jluciani@novell.com>
*
***********************************************************************/
//===[ Include files ]=====================================================
#include "internal.h"
//===[ Type definitions ]==================================================
//===[ Function prototypes ]===============================================
//===[ Global variables ]==================================================

View File

@ -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 <jluciani@novell.com>
*
***********************************************************************/
#ifndef _PLATFORM_H_
#define _PLATFORM_H_
//===[ Include files ]=====================================================
#include <windows.h>
#include <stdio.h>
#include <winerror.h>
#include <security.h>
#include <sspi.h>
//===[ 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_

View File

@ -0,0 +1,12 @@
#######################################################
# #
# CASA Authentication Token System configuration file #
# for module: #
# #
# PwdAuthenticate #
# #
#######################################################
LibraryName \Program Files\novell\casa\lib\pwmech.dll

View File

@ -0,0 +1,27 @@
/***********************************************************************
*
* 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.

View File

@ -0,0 +1,14 @@
/***********************************************************************
*
* TODO for pwmech
*
***********************************************************************/
INTRODUCTION
This file contains a list of the items still outstanding for pwmech.
OUTSTANDING ITEMS
- Implementation of Linux specific code.

View File

@ -0,0 +1,359 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
//===[ Include files ]=====================================================
#include "internal.h"
//===[ Type definitions ]==================================================
//===[ Function prototypes ]===============================================
//===[ Global variables ]==================================================
//++=======================================================================
static
CasaStatus
GetUserCredentials(
IN const char *pRealm,
INOUT char **ppUsername,
INOUT char **ppPassword)
//
// Arguments:
// pRealm -
// The realm to which the credentials apply.
//
// 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;
int32_t credtype = SSCS_CRED_TYPE_BASIC_F;
SSCS_BASIC_CREDENTIAL credential = {0};
SSCS_SECRET_ID_T secretId = {0};
SSCS_SECRET_ID_T sharedSecretId = {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(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,
NULL);
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(secretId.id, "Desktop");
rcode = miCASAGetCredential(0,
&secretId,
NULL,
&credtype,
&credential,
NULL);
}
}
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(credential.username) + 1);
if (pUsername)
{
// Copy the username into the buffer that we will be returning
strcpy(pUsername, credential.username);
// Allocate a buffer to return the password
pPassword = (char*) malloc(strlen(credential.password) + 1);
if (pPassword)
{
// Copy the password into the buffer that we will be returning
strcpy(pPassword, credential.password);
// 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);
}
}
// 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,
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.
//
// 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
|| pMechInfo == 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, &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;
}
//++=======================================================================
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;
}
//++=======================================================================
//++=======================================================================
//++=======================================================================

View File

@ -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 <jluciani@novell.com>
*
***********************************************************************/
//===[ 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;
}
//++=======================================================================
//++=======================================================================
//++=======================================================================

View File

@ -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 <jluciani@novell.com>
*
***********************************************************************/
#ifndef _INTERNAL_H_
#define _INTERNAL_H_
//===[ Include files ]=====================================================
#include "platform.h"
#include <micasa_types.h>
#include <micasa_mgmd.h>
#include <sscs_utf8.h>
#include <casa_status.h>
#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,
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_

View File

@ -0,0 +1,183 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="pwd"
ProjectGUID="{5499F624-F371-4559-B4C2-A484BCE892FD}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)client\mechanisms\pwd\windows\$(ConfigurationName)"
IntermediateDirectory="$(SolutionDir)client\mechanisms\pwd\windows\$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="windows;.;..\..;..\..\..\..\include"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/EXPORT:GetAuthTokenInterface"
AdditionalDependencies="micasa.lib"
OutputFile="$(OutDir)/pwmech.dll"
LinkIncremental="1"
AdditionalLibraryDirectories="C:\Program Files\novell\CASA\lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/pw.pdb"
SubSystem="0"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"
CommandLine="mkdir \&quot;Program Files&quot;\novell\
mkdir \&quot;Program Files&quot;\novell\casa
mkdir \&quot;Program Files&quot;\novell\casa\lib\
mkdir \&quot;Program Files&quot;\novell\casa\etc\
mkdir \&quot;Program Files&quot;\novell\casa\etc\auth\
mkdir \&quot;Program Files&quot;\novell\casa\etc\auth\mechanisms\
copy PwdAuthenticate.conf \&quot;Program Files&quot;\novell\casa\etc\auth\mechanisms\PwdAuthenticate.conf
copy $(OutDir)\pwmech.dll \&quot;Program Files&quot;\novell\casa\lib\pwmech.dll
"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)client\mechanisms\pwd\windows\$(ConfigurationName)"
IntermediateDirectory="$(SolutionDir)client\mechanisms\pwd\windows\$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="windows;.;..\..;..\..\..\..\include"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
RuntimeLibrary="4"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/EXPORT:GetAuthTokenInterface"
AdditionalDependencies="micasa.lib"
OutputFile="$(OutDir)/pwmech.dll"
LinkIncremental="1"
AdditionalLibraryDirectories="C:\Program Files\novell\CASA\lib"
GenerateDebugInformation="TRUE"
SubSystem="0"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"
CommandLine="mkdir \&quot;Program Files&quot;\novell\
mkdir \&quot;Program Files&quot;\novell\casa
mkdir \&quot;Program Files&quot;\novell\casa\lib\
mkdir \&quot;Program Files&quot;\novell\casa\etc\
mkdir \&quot;Program Files&quot;\novell\casa\etc\auth\
mkdir \&quot;Program Files&quot;\novell\casa\etc\auth\mechanisms\
copy PwdAuthenticate.conf \&quot;Program Files&quot;\novell\casa\etc\auth\mechanisms\PwdAuthenticate.conf
copy $(OutDir)\pwmech.dll \&quot;Program Files&quot;\novell\casa\lib\pwmech.dll
"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath=".\windows\dllsup.c">
</File>
<File
RelativePath=".\get.c">
</File>
<File
RelativePath=".\interface.c">
</File>
<File
RelativePath=".\windows\platform.c">
</File>
<File
RelativePath=".\PwdAuthenticate.conf"
DeploymentContent="TRUE">
</File>
<File
RelativePath=".\windows\pwmech.def">
</File>
<File
RelativePath=".\util.c">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
<File
RelativePath=".\internal.h">
</File>
<File
RelativePath=".\windows\platform.h">
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,282 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
//===[ 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;
}
//++=======================================================================
//++=======================================================================
//++=======================================================================

View File

@ -0,0 +1,132 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
//===[ 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_PW_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);
}
//=========================================================================
//=========================================================================

View File

@ -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 <jluciani@novell.com>
*
***********************************************************************/
//===[ Include files ]=====================================================
#include "internal.h"
//===[ Type definitions ]==================================================
//===[ Function prototypes ]===============================================
//===[ Global variables ]==================================================

View File

@ -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 <jluciani@novell.com>
*
***********************************************************************/
#ifndef _PLATFORM_H_
#define _PLATFORM_H_
//===[ Include files ]=====================================================
#include <windows.h>
#include <stdio.h>
#include <winerror.h>
//===[ 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, "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_

View File

@ -0,0 +1,10 @@
LIBRARY PWMECH
DESCRIPTION 'CASA PW Authentication Mechanism Library.'
EXPORTS
; DllRegisterServer PRIVATE
; DllUnregisterServer PRIVATE
; DllGetClassObject PRIVATE
GetAuthTokenInterface PRIVATE
; DllCanUnloadNow PRIVATE

View File

@ -0,0 +1,513 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
#include <windows.h>
#include "casa_c_authtoken.h"
// Globals
char usageString[] = "usage: test -a serverAddress -p serverPort [-h]\n";
char *pServerAddress = NULL;
int serverPort = 0;
BOOLEAN execHttpTest = FALSE;
/***********************************************************************
*
* 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;
}
/***********************************************************************
*
* 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[4096];
int authTokenLen = sizeof(authToken);
// Obtain an authentication token for the testService
retStatus = ObtainAuthToken("testService", 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;
int winsockStartupResult;
WSADATA winsockData;
printf("-NonHttpTest- ObtainAuthToken succedded, tokenlen = %d\n", authTokenLen);
// Send the token to the server
//
// First initialize winsock
if ((winsockStartupResult = WSAStartup(MAKEWORD(2,2), &winsockData)) == 0)
{
// 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", WSAGetLastError());
}
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);
}
// Close winsock
WSACleanup();
}
else
{
printf("-NonHttpTest- WSAStartup failed, error = %d\n", winsockStartupResult);
}
}
}
/***********************************************************************
*
* HttpTest()
*
***********************************************************************/
void HttpTest(void)
{
CasaStatus retStatus;
char authToken[4096];
int authTokenLen = sizeof(authToken);
// Obtain an authentication token for the testService
retStatus = ObtainAuthToken("testService", 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;
int winsockStartupResult;
WSADATA winsockData;
//printf("ObtainAuthToken succedded, token = %s\n", authToken);
printf("-HttpTest- ObtainAuthToken succedded, tokenlen = %d\n", authTokenLen);
// Send the token to the server
//
// First initialize winsock
if ((winsockStartupResult = WSAStartup(MAKEWORD(2,2), &winsockData)) == 0)
{
// 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", WSAGetLastError());
}
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)
{
char *pEncodedCredentials;
memcpy(pBasicCredentials, CasaPrincipal, sizeof(CasaPrincipal));
strcat(pBasicCredentials, authToken);
// Now Base64 encode the credentials
if (EncodeData(pBasicCredentials, strlen(pBasicCredentials), &pEncodedBasicCredentials, &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);
}
// Close winsock
WSACleanup();
}
else
{
printf("-HttpTest- WSAStartup failed, error = %d\n", winsockStartupResult);
}
}
}
/***********************************************************************
*
* 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], strlen(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)
{
// 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;
}

View File

@ -0,0 +1,142 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="test"
ProjectGUID="{6034EBF1-0838-45C4-A538-A41A31EC8F46}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="Debug"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\..\include"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="authtoken.lib ws2_32.lib"
OutputFile="$(OutDir)/test.exe"
LinkIncremental="2"
AdditionalLibraryDirectories="&quot;C:\Program Files\novell\CASA\lib&quot;"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/test.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"
CommandLine="copy ..\windows\debug\authtoken.dll debug\authtoken.dll"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="Release"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\..\..\include"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="4"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="authtoken.lib ws2_32.lib"
OutputFile="$(OutDir)/test.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="&quot;C:\Program Files\novell\CASA\lib&quot;"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath=".\CASA_Auth.cpp">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
</Filter>
<File
RelativePath=".\ReadMe.txt">
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -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 <jluciani@novell.com>
*
***********************************************************************/
//===[ 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;
}
//++=======================================================================
//++=======================================================================
//++=======================================================================

View File

@ -0,0 +1,10 @@
LIBRARY AUTHTOKEN
DESCRIPTION 'CASA Authentication Token Library.'
EXPORTS
; DllRegisterServer PRIVATE
; DllUnregisterServer PRIVATE
; DllGetClassObject PRIVATE
ObtainAuthToken PRIVATE
; DllCanUnloadNow PRIVATE

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,132 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
//===[ 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("CASAAUTH -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);
}
//=========================================================================
//=========================================================================

View File

@ -0,0 +1,549 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
//===[ 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 ]==================================================
// Global synchronization mutex for the user
static
HANDLE hUserMutex;
// Normalized host name cache list head
static
LIST_ENTRY normalizedHostNameCacheListHead;
// Synchronization mutex for the normalized host name cache
static
HANDLE hNormalizedHostNameCacheMutex;
// Authentication mechanism configuration file folder
char mechConfigFolder[] = "\\Program Files\\Novell\\Casa\\Etc\\Auth\\Mechanisms";
// Path separator
char pathCharString[] = "\\";
//++=======================================================================
CasaStatus
CreateUserMutex(void)
//
// 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)
{
hUserMutex = CreateMutex(&mutexAttributes,
FALSE,
mutexName);
if (hUserMutex == NULL)
{
DbgTrace(0, "-CreateUserMutex- CreteMutex 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- Un-expected 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(void)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// L2
//=======================================================================--
{
DbgTrace(2, "-AcquireUserMutex- Start\n", 0);
WaitForSingleObject(hUserMutex, INFINITE);
DbgTrace(2, "-AcquireUserMutex- End\n", 0);
}
//++=======================================================================
void
ReleaseUserMutex(void)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// L2
//=======================================================================--
{
DbgTrace(2, "-ReleaseUserMutex- Start\n", 0);
if (ReleaseMutex(hUserMutex) == 0)
{
DbgTrace(0, "-ReleaseUserMutex- ReleaseMutex failed, error = %d\n", GetLastError());
}
DbgTrace(2, "-ReleaseUserMutex- 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;
}
//++=======================================================================
//++=======================================================================
//++=======================================================================

View File

@ -0,0 +1,114 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
//===[ Include files ]=====================================================
#include <winsock2.h>
#include <windows.h>
#include <stdio.h>
#include <aclapi.h>
#include <winerror.h>
#include <ws2tcpip.h>
#include <winhttp.h>
//===[ 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("AuthToken %s", printBuff); \
// } \
//}
#define DbgTrace(LEVEL, X, Y) { \
char formatBuff[128]; \
char printBuff[256]; \
if (LEVEL == 0 || DebugLevel >= LEVEL) \
{ \
strcpy(formatBuff, "AuthToken "); \
strncat(formatBuff, X, sizeof(formatBuff) - 10); \
_snprintf(printBuff, sizeof(printBuff), formatBuff, Y); \
OutputDebugString(printBuff); \
} \
}
#define bool BOOLEAN
#define true TRUE
#define false FALSE
//
// Auth Cache Entry definition
//
typedef struct _AuthCacheEntry
{
LIST_ENTRY listEntry;
int refCount;
DWORD creationTime;
DWORD expirationTime;
BOOL doesNotExpire;
char *pHostName;
char *pCacheKeyName;
char *pToken;
int status;
} AuthCacheEntry, *PAuthCacheEntry;
//
// Rpc Session definition
//
typedef struct _RpcSession
{
HINTERNET hSession;
HINTERNET hConnection;
} RpcSession, *PRpcSession;
//
// Other definitions
//
#define LIB_HANDLE HMODULE
//===[ Inlines functions ]===============================================
//===[ Function prototypes ]===============================================
//===[ Global externals ]==================================================
//===[ External prototypes ]===============================================
//=========================================================================

View File

@ -0,0 +1,498 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
//===[ 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;
}
//++=======================================================================
RpcSession*
OpenRpcSession(
IN char *pHostName)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// L2
//=======================================================================--
{
RpcSession *pSession;
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));
// 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,
8080, /*INTERNET_DEFAULT_HTTP_PORT,*/
0);
if (pSession->hConnection == NULL)
{
DbgTrace(0, "-OpenRpcSession- Failed to open connection, error = %d\n", GetLastError());
// Free allocated resources
WinHttpCloseHandle(pSession->hSession);
free(pSession);
pSession = NULL;
}
// Free the host name wide string buffer
free(pWideHostName);
}
else
{
DbgTrace(0, "-OpenRpcSession- Error converting host name to wide string\n", 0);
// Free allocated resources
WinHttpCloseHandle(pSession->hSession);
free(pSession);
pSession = NULL;
}
}
else
{
DbgTrace(0, "-OpenRpcSession- Failed to open session, error = %d\n", GetLastError());
}
}
else
{
DbgTrace(0, "-OpenRpcSession- Failed to allocate buffer for rpc session\n", 0);
}
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 the space allocated for the session
free(pSession);
DbgTrace(1, "-CloseRpcSession- End\n", 0);
}
//++=======================================================================
static
CasaStatus
InternalRpc(
IN RpcSession *pSession,
IN char *pMethod,
IN bool secure,
IN char *pRequestData,
INOUT char **ppResponseData,
INOUT int *pResponseDataLen)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// L2
//=======================================================================--
{
CasaStatus retStatus = CASA_STATUS_SUCCESS;
char rpcTarget[256];
LPWSTR pWideRpcTarget;
int wideRpcTargetLen;
WCHAR sendHeaders[] = L"Content-Type: text/html";
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;
// Open a request handle
hRequest = WinHttpOpenRequest(pSession->hConnection,
L"POST",
pWideRpcTarget,
NULL,
WINHTTP_NO_REFERER,
WINHTTP_DEFAULT_ACCEPT_TYPES,
secure? WINHTTP_FLAG_REFRESH | WINHTTP_FLAG_SECURE : WINHTTP_FLAG_REFRESH);
if (hRequest)
{
int reqDataLen = (int) strlen(pRequestData);
// Send the request
if (WinHttpSendRequest(hRequest,
sendHeaders,
-1,
pRequestData,
reqDataLen,
reqDataLen,
0))
{
// 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();
DbgTrace(0, "-InternalRpc- Unsuccessful send http request, error = %d\n", error);
if (error == ERROR_WINHTTP_CANNOT_CONNECT)
{
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_AUTH_SERVER_UNAVAILABLE);
}
else
{
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);
}
// 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 bool secure,
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,
secure,
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;
}
//++=======================================================================
//++=======================================================================
//++=======================================================================

View File

@ -0,0 +1,279 @@
#######################################################################
#
# 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(include/casa_s_authtoken.h)
AC_CANONICAL_SYSTEM
AM_INIT_AUTOMAKE(CASA_auth_token_native, 0.1.1)
RELEASE=`date +%Y%m%d_%H%M`
AC_SUBST(RELEASE)
AM_MAINTAINER_MODE
#
# Check for a valid C# compiler
#
#AC_CHECK_PROG(CSC, csc, csc)
#test -z "$CSC" && AC_CHECK_PROG(CSC, mcs, mcs)
#test -z "$CSC" && AC_MSG_ERROR([no acceptable C Sharp compiler found in \$PATH])
#
# Check for valid C# compiler in linux
#
case $host_os in
cygwin*)
;;
*)
AC_CHECK_PROG(CSC, csc, csc)
test -z "$CSC" && AC_CHECK_PROG(CSC, mcs, mcs)
test -z "$CSC" && AC_MSG_ERROR([no acceptable C Sharp compiler found in \$PATH])
;;
esac
case $CSC in
#
# Mono-specific configuration
#
mcs)
CSC_EXEFLAG=/target:exe
CSC_LIBFLAG=/target:library
CSC_EXEFLAG=/target:exe
CSC_WINEXEFLAG=/target:winexe
CSCFLAGS='/d:MONO /warn:4 /d:TRACE -d:LINUX'
CSCFLAGS_DEBUG="/debug+ /d:DEBUG"
CSCFLAGS_OPTIMIZE="/optimize+"
MONO=mono
MONO_DEBUG='mono --debug'
MONO_PATH=
SYSTEM_XML='System.Xml.dll'
;;
#
# .NET-specific configuration
#
csc)
CSC_EXEFLAG=/target:exe
CSC_LIBFLAG=/target:library
CSC_EXEFLAG=/target:exe
CSC_WINEXEFLAG=/target:winexe
CSCFLAGS='/d:DOTNET /warn:4 /d:TRACE /nologo'
CSCFLAGS_DEBUG="/debug+ /d:DEBUG"
CSCFLAGS_OPTIMIZE="/optimize+"
MONO=
MONO_DEBUG=
MONO_PATH=
SYSTEM_XML='System.XML.dll'
;;
esac
AC_SUBST(CSC)
AC_SUBST(CSC_EXEFLAG)
AC_SUBST(CSC_LIBFLAG)
AC_SUBST(CSC_WINEXEFLAG)
AC_SUBST(CSCFLAGS)
AC_SUBST(CSCFLAGS_DEBUG)
AC_SUBST(MONO)
AC_SUBST(MONO_PATH)
AC_SUBST(SYSTEM_XML)
SRCDIR='$(top_srcdir)'
DOCDIR="$SRCDIR/doc"
TOOLDIR='$(top_srcdir)/tools'
AC_SUBST(SRCDIR)
AC_SUBST(DOCDIR)
AC_SUBST(TOOLDIR)
EMPTY=
SPACE='$(EMPTY) $(EMPTY)'
AC_SUBST(EMPTY)
AC_SUBST(SPACE)
#
# Check for operating system and set TARGET_OS
#
case $host_os in
cygwin*)
TARGET_OS='windows'
;;
*)
TARGET_OS='linux'
;;
esac
AC_SUBST(TARGET_OS)
AM_CONDITIONAL(LINUX, test "$TARGET_OS" = "linux")
AM_CONDITIONAL(WINDOWS, test "$TARGET_OS" = "windows")
#
# Check for architecture and set TARGET_ARCH
# ia64 needs to be treated as non64.
case $target_cpu in
x86_64|p*pc64|s390x)
LIB=lib64
;;
*ia64|*)
LIB=lib
;;
esac
AC_SUBST(LIB)
AM_CONDITIONAL(LIB64, test "$LIB" = lib64)
#
#
# Set platform-specific variables
#
case $TARGET_OS in
#
# Linux-specific configuration
#
linux)
#
# Set variables
#
COMMON_CLEAN_FILES=''
ICON_EXT='.ico'
ICON_FLAG='/resource:'
PLATFORM_SUBDIRS=$LINUX_SUBDIRS
SEP='/'
LINK=gcc
;;
#
# Windows-specific configuration
#
windows)
COMMON_CLEAN_FILES='*.suo */*.suo *.csproj.user */*.csproj.user bin obj */bin */obj *.xml */*.xml *.pdb */*.pdb'
ICON_EXT='.ico'
ICON_FLAG='/win32icon:'
PLATFORM_SUBDIRS=$WINDOWS_SUBDIRS
SEP='$(EMPTY)\\$(EMPTY)'
LINK=link.exe
;;
esac
AC_SUBST(COMMON_CLEAN_FILES)
AC_SUBST(ICON_EXT)
AC_SUBST(ICON_FLAG)
AC_SUBST(PLATFORM_SUBDIRS)
AC_SUBST(SEP)
AC_SUBST(LINK)
#
# Run standard macros
#
AM_PROG_CC_STDC
AC_PROG_INSTALL
AC_HEADER_STDC
#######
#
# set CFLAGS
#
case $host_os in
linux*)
CFLAGS="$CFLAGS"
;;
cygwin*)
CC=cl.exe
CFLAGS="-D WIN32 -D SSCS_WIN32_PLAT_F -D N_PLAT_CLIENT -MT -Ox"
;;
esac
#
# Handle --enable-debug
#
AC_ARG_ENABLE(debug, [
--enable-debug configure the Makefiles to build in DEBUG mode],
[case "${enableval}" in
yes) enable_debug=true ;;
no) enable_debug=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-debug) ;;
esac],[enable_debug=false])
AM_CONDITIONAL(DEBUG, test x$enable_debug = xtrue)
if test "$enable_debug" = "true"
then
# Build debug version.
# CFLAGS="$CFLAGS_DEBUG $CFLAGS -DDBG -DDEBUG"
CFLAGS="$CFLAGS_DEBUG $CFLAGS -g -DDBG -DDEBUG \
-fPIC -DPIC -DSSCS_LINUX_PLAT_F -O2 -fmessage-length=0 -Wall \
-D_REENTRANT -DALIGNMENT -DN_PLAT_UNIX \
-DUNIX -DLINUX -DIAPX38"
CSCFLAGS="$CSCFLAGS_DEBUG $CSCFLAGS"
CXXFLAGS="$CXXFLAGS_DEBUG $CXXFLAGS"
DEVENV_CONFIGURATION=Debug
MONO=$MONO_DEBUG
else
# Build optimized version.
CFLAGS="$CFLAGS_OPTIMIZE $CFLAGS -g -fPIC -DPIC \
-DSSCS_LINUX_PLAT_F -O2 -fmessage-length=0 -Wall \
-D_REENTRANT -DALIGNMENT -DN_PLAT_UNIX \
-DUNIX -DLINUX -DIAPX38"
CSCFLAGS="$CSCFLAGS_OPTIMIZE $CSCFLAGS"
CXXFLAGS="$CXXFLAGS_OPTIMIZE $CXXFLAGS"
DEVENV_CONFIGURATION=Release
fi
AC_SUBST(CSCFLAGS)
AC_SUBST(DEVENV_CONFIGURATION)
##comment out due to build failure
# Check for GCC version to add fstack-protector flag
#
#GCC_VER="`gcc -dumpversion`"
#case "$GCC_VER" in
# 3*)
# ;;
# 4*)
# CFLAGS="$CFLAGS -fstack-protector"
# ;;
# *)
# ;;
#esac
AC_SUBST(GCC_VER)
#
# Configure PKG_CONFIG
#
AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
if test "x$PKG_CONFIG" = "xno"; then
AC_MSG_ERROR([You need to install pkg-config])
fi
#
# Configure files
#
AC_OUTPUT([
Makefile
package/Makefile
package/linux/Makefile
package/linux/CASA_auth_token_native.spec
include/Makefile
server/Makefile
server/AuthTokenValidate/Makefile
server/AuthTokenValidate/linux/Makefile
server/AuthTokenValidate/idenTokenProviders/Makefile
server/AuthTokenValidate/idenTokenProviders/casa/Makefile
server/AuthTokenValidate/idenTokenProviders/casa/linux/Makefile
server/PamSupport/Makefile
server/PamSupport/linux/Makefile
server/ApacheSupport/Makefile
server/ApacheSupport/2.2/Makefile
server/ApacheSupport/2.2/linux/Makefile
])

View File

@ -0,0 +1,40 @@
#######################################################################
#
# Copyright (C) 2006 Novell, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# Author: Juan Carlos Luciani <jluciani@novell.com>
#
#######################################################################
SUBDIRS =
DIST_SUBDIRS =
CFILES =
EXTRA_DIST = *.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

View File

@ -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 <jluciani@novell.com>
*
***********************************************************************/
#ifndef _CASA_C_AUTHTOKEN_H_
#define _CASA_C_AUTHTOKEN_H_
#if defined(__cplusplus) || defined(c_plusplus)
extern "C"
{
#endif
//===[ Include files ]=====================================================
#include <micasa_types.h>
#include <casa_status.h>
//===[ 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_

View File

@ -0,0 +1,305 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
#ifndef _CASA_S_AUTHTOKEN_H_
#define _CASA_S_AUTHTOKEN_H_
#if defined(__cplusplus) || defined(c_plusplus)
extern "C"
{
#endif
//===[ Include files ]=====================================================
#include <micasa_types.h>
#include <casa_status.h>
//===[ Type definitions ]==================================================
#ifndef SSCS_CALL
#if defined(WIN32)
#define SSCS_CALL __stdcall
#else
#define SSCS_CALL
#endif
#endif
//===[ Function prototypes ]===============================================
//===[ Global variables ]==================================================
/**************************************************************************
***************************************************************************
** **
** Principal Interface Definition **
** **
***************************************************************************
**************************************************************************/
//++=======================================================================
typedef
int
(SSCS_CALL *PFNPrincipalIf_AddReference)(
IN const void *pIfInstance);
//
// Arguments:
// pIfInstance -
// Pointer to interface object.
//
// Returns:
// Interface reference count.
//
// Description:
// Increases interface reference count.
//=======================================================================--
//++=======================================================================
typedef
void
(SSCS_CALL *PFNPrincipalIf_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 *PFNPrincipalIf_GetIdentityId)(
IN const void *pIfInstance,
INOUT char *pIdentIdBuf,
INOUT int *pIdentIdLen);
//
// Arguments:
// pIfInstance -
// Pointer to interface object.
//
// pIdentIdBuf -
// Pointer to buffer that will receive the identity id. The returned
// id will be in the form of a NULL terminated string.
//
// pIdentIdBufLen -
// Pointer to variable with the length of the buffer pointed by
// pIdentIdBuf. On exit it contains the length of the returned id
// (including the NULL terminator).
//
//
// Returns:
// Casa Status
//
// Description:
// Get the identity id associated with the identity token.
//=======================================================================--
//++=======================================================================
typedef
CasaStatus
(SSCS_CALL *PFNPrincipalIf_GetSourceName)(
IN const void *pIfInstance,
INOUT char *pSourceNameBuf,
INOUT int *pSourceNameLen);
//
// Arguments:
// pIfInstance -
// Pointer to interface object.
//
// pSourceNameBuf -
// Pointer to buffer that will receive the name associated with the
// identity information source. The returned name will be in the form
// of a NULL terminated string.
//
// pSourceNameBufLen -
// Pointer to variable with the length of the buffer pointed by
// pSourceNameBuf. On exit it contains the length of the returned
// name (including the NULL terminator).
//
//
// Returns:
// Casa Status
//
// Description:
// Get the name of the identity source associated with the identity token.
//=======================================================================--
//++=======================================================================
typedef
CasaStatus
(SSCS_CALL *PFNPrincipalIf_GetSourceUrl)(
IN const void *pIfInstance,
INOUT char *pSourceUrlBuf,
INOUT int *pSourceUrlLen);
//
// Arguments:
// pIfInstance -
// Pointer to interface object.
//
// pSourceUrlBuf -
// Pointer to buffer that will receive the URL associated with the
// identity information source. The returned URL will be in the form
// of a NULL terminated string.
//
// pSourceUrlBufLen -
// Pointer to variable with the length of the buffer pointed by
// pSourceUrlBuf. On exit it contains the length of the returned
// URL (including the NULL terminator).
//
//
// Returns:
// Casa Status
//
// Description:
// Get the URL to the identity source associated with the identity token.
//=======================================================================--
//++=======================================================================
typedef
CasaStatus
(SSCS_CALL *PFNPrincipalIf_AttributeEnumerate)(
IN const void *pIfInstance,
INOUT int *pEnumHandle,
INOUT char *pAttribNameBuf,
INOUT int *pAttribNameLen,
INOUT char *pAttribValueBuf,
INOUT int *pAttribValueLen);
//
// Arguments:
// pIfInstance -
// Pointer to interface object.
//
// pEnumHandle -
// Pointer to enumeration handle. Must be set to 0 to start an
// enumeration. Note the enumeration handle advances if the
// function returns success.
//
// pAttribNameBuf -
// Pointer to buffer that will receive the identity attribute name. The
// returned name will be in the form of a NULL terminated string.
//
// pAttribNameLen -
// Pointer to variable with the length of the buffer pointed by
// pAttribNameBuf. On exit it contains the length of the returned
// name (including the NULL terminator).
//
// pAttribValueBuf -
// Pointer to buffer that will receive the identity attribute value. The
// returned value will be in the form of a NULL terminated string.
//
// pAttribValueLen -
// Pointer to variable with the length of the buffer pointed by
// pAttribValueBuf. On exit it contains the length of the returned
// value (including the NULL terminator).
//
//
// Returns:
// Casa Status
//
// Description:
// Enumerates through the attributes associated with the identity token.
//=======================================================================--
//
// Principal Interface Object
//
typedef struct _PrincipalIf
{
PFNPrincipalIf_AddReference addReference;
PFNPrincipalIf_ReleaseReference releaseReference;
PFNPrincipalIf_GetIdentityId getIdentityId;
PFNPrincipalIf_GetSourceName getSourceName;
PFNPrincipalIf_GetSourceUrl getSourceUrl;
PFNPrincipalIf_AttributeEnumerate attributeEnumerate;
} PrincipalIf, *PPrincipalIf;
/**************************************************************************
***************************************************************************
** **
** Validate Authentication Token API **
** **
***************************************************************************
**************************************************************************/
//++=======================================================================
extern CasaStatus SSCS_CALL
ValidateAuthToken(
IN const char *pServiceName,
IN const char *pTokenBuf,
IN const int tokenBufLen,
INOUT PrincipalIf **ppPrincipalIf);
//
// Arguments:
// pServiceName -
// Pointer to NULL terminated string that contains the
// name of the service targeted by the token.
//
// 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.
//
// tokenBufLen -
// Length of the data contained within the buffer pointed
// at by pTokenBuf.
//
// ppPrincipalIf -
// Pointer to variable that will receive a pointer to a principal
// interface with information about the authenticated entity.
// IMPORTANT NOTE: The caller is responsible for releasing the
// interface after it is done with it to avoid a resource leak.
//
// Returns:
// Casa status.
//
// Description:
// Validates authentication token.
//
//=======================================================================--
#if defined(__cplusplus) || defined(c_plusplus)
}
#endif // #if defined(__cplusplus) || defined(c_plusplus)
#endif // #ifndef _CASA_S_AUTHTOKEN_H_

View File

@ -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 <micasa_types.h>
//===[ 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_

View File

@ -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 <jluciani@novell.com>
*
***********************************************************************/
#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 "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>"
#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_

View File

@ -0,0 +1,38 @@
#######################################################################
#
# Copyright (C) 2006 Novell, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# Author: Juan Carlos Luciani <jluciani@novell.com>
#
#######################################################################
SUBDIRS = linux
DIST_SUBDIRS = linux
EXTRA_DIST =
.PHONY: package package-clean package-install package-uninstall
package package-clean package-install package-uninstall:
$(MAKE) -C $(TARGET_OS) $@
clean-local:
if [ -d lib ]; then rm -rf lib; fi
maintainer-clean-local:
rm -f Makefile.in

View File

@ -0,0 +1,227 @@
#
# spec file for the CASA-auth-token native packages.
#
# Copyright (c) 2006 SUSE LINUX Products GmbH, Nuernberg, Germany.
# This file and all modifications and additions to the pristine
# package are under the same license as the package itself.
#
# Please submit bugfixes or comments via http://bugs.opensuse.org
#
# norootforbuild
# For debug build, please replace Release to Debug and set debug_opt to --enable-debug
%define cfg Release
%define debug_opt ""
Name: @PACKAGE@
URL: http://www.novell.com/products
BuildRequires: libstdc++ libgcc gcc-c++ glib2-devel krb5-devel libgssapi libstdc++-devel pam-devel pkgconfig apache2-devel update-alternatives mono-devel CASA-devel expat
%define prefix /usr
License: LGPL
Group: Applications/System
Autoreqprov: on
%define bldno 1.0.0
Version: @VERSION@
Release: 0
Summary: Novell Common Authentication Services Adapter Authentication Token Infrastructure (CASA-auth-token)
Source: %{name}-%{version}.tar.bz2
BuildRoot: %{_tmppath}/%{name}-%{version}-build
Requires: expat
PreReq: %fillup_prereq %insserv_prereq
%description
CASA-auth-token is an authentication token infrastructure with support for multiple
authentication mechanisms with an emphasis on providing a scalable single
sign-on solution.
A key feature of CASA-auth-token is that its authentication tokens contain identity
information about the entity being authenticated. This information is made available
to the consuming services. The amount of information contained in the tokens is
configured on a per-service basis. Because of this feature, we say that CASA-auth-token
projects an "Authenticated Identity".
This package contains the CASA (Common Authentication Services Adapter)
authentication token infrastructure lower level libraries for token
verification from native code ("C"). It is recomended that this library
not be invoked directly by applications, instead it is recomended that
appplication invoke its services through the support modules provided to
integrate with PAM or the Apache Web Server.
%package -n CASA-auth-token-pam-support
Summary: Libraries needed for PAM applications development.
Group: Applications/System
Requires: CASA-auth-token-server-support pam
%description -n CASA-auth-token-pam-support
This package contains the CASA (Common Authentication Services Adapter)
authentication token infrastructure PAM module for token verification.
%package -n CASA-auth-token-apache2_2-support
Summary: Libraries needed for Apache 2.2 applications development.
Group: Applications/System
Requires: apache2 CASA-auth-token-server-support
%description -n CASA-auth-token-apache2_2-support
This package contains the CASA (Common Authentication Services Adapter)
authentication token infrastructure Apache v2.2 authentication provider
module for token verification. The module expects that users authenticate
utilizing the HTTP Basic authentication scheme and that the password utilized consist
of a CASA authentication token. Information about the authenticated identity is
made available to other Apache modules via the Apache request environment variable.
%package -n CASA-auth-token-devel
Summary: Include files needed for applications development.
Group: Applications/System
Requires: CASA-devel CASA-auth-token-server-support CASA-auth-token-jaas-support CASA-auth-token-pam-support CASA-auth-token-apache2_2-support CASA-auth-token-service
%description -n CASA-auth-token-devel
This package contains the files necessary for the development of client and
server applications that utilize the CASA (Common Authentication Service Adapter)
authentication token infrastructure for authentication.
%prep
%setup -q
#%patch
%if %{_lib} == "lib64"
%define binsource bin64
%else
%define binsource bin
%endif
%build
export PATH=.:$PATH:/usr/%_lib/qt3/bin
%if %suse_version > 1000
export CFLAGS="$CFLAGS $RPM_OPT_FLAGS -fstack-protector"
%endif
./autogen.sh
make
%install
## Prime the file system ##
install -d %{buildroot}%{prefix}
install -d %{buildroot}%{prefix}/%{_lib}
install -d %{buildroot}%{prefix}/%{_lib}/security
install -d %{buildroot}%{prefix}/include
## CASA-auth-token-server-support ##
# Libs
install -m 755 %{_lib}/%{cfg}/libcasa_s_authtoken.so %{buildroot}%{prefix}/%{_lib}/libcasa_s_authtoken.so.%{bldno}
# Lib Symbolic Links
ln -sf libcasa_s_authtoken.so.%{bldno} %{buildroot}%{prefix}/%{_lib}/libcasa_s_authtoken.so
ln -sf libcasa_s_authtoken.so.%{bldno} %{buildroot}%{prefix}/%{_lib}/libcasa_s_authtoken.so.1
## CASA-auth-token-pam-support ##
# Libs
install -m 755 %{_lib}/%{cfg}/pam_casaauthtok.so %{buildroot}%{prefix}/%{_lib}/security/pam_casaauthtok.so.%{bldno}
#install -m 755 %{_lib}/%{cfg}/pam_casaauthtok.so %{buildroot}%{prefix}/%{_lib}/security/pam_casaauthtok.so
# Lib Symbolic Links
ln -sf pam_casaauthtok.so.%{bldno} %{buildroot}%{prefix}/%{_lib}/security/pam_casaauthtok.so
ln -sf pam_casaauthtok.so.%{bldno} %{buildroot}%{prefix}/%{_lib}/security/pam_casaauthtok.so.1
## CASA-auth-token-apache2_2-support ##
# Libs
install -m 755 %{_lib}/%{cfg}/mod_authn_casa.so %{buildroot}%{prefix}/%{_lib}/mod_authn_casa.so.%{bldno}
# Lib Symbolic Links
ln -sf mod_authn_casa.so.%{bldno} %{buildroot}%{prefix}/%{_lib}/mod_authn_casa.so
ln -sf mod_authn_casa.so.%{bldno} %{buildroot}%{prefix}/%{_lib}/mod_authn_casa.so.1
## CASA-auth-token-devel ##
# Header Files
install -m 644 include/casa_c_authtoken.h %{buildroot}%{prefix}/include
install -m 644 include/casa_s_authtoken.h %{buildroot}%{prefix}/include
%clean
rm -rf $RPM_BUILD_ROOT
## CASA-auth-token-server-support ##
%pre
# Nothing to do in this pre script
%post
/sbin/ldconfig
%preun
# Nothing to do in this preun script
%postun
# Nothing to do in this postun script
%files
%defattr(-,root,root)
%{prefix}/%{_lib}/libcasa_s_authtoken.so.%{bldno}
%{prefix}/%{_lib}/libcasa_s_authtoken.so
%{prefix}/%{_lib}/libcasa_s_authtoken.so.1
## CASA-auth-token-pam-support ##
%pre -n CASA-auth-token-pam-support
# Nothing to do in this pre script
%post -n CASA-auth-token-pam-support
/sbin/ldconfig
%preun -n CASA-auth-token-pam-support
# Nothing to do in this preun script
%postun -n CASA-auth-token-pam-support
# Nothing to do in this postun script
%files -n CASA-auth-token-pam-support
%defattr(-,root,root)
%dir %{prefix}/%{_lib}/security
%{prefix}/%{_lib}/security/pam_casaauthtok.so.%{bldno}
%{prefix}/%{_lib}/security/pam_casaauthtok.so
%{prefix}/%{_lib}/security/pam_casaauthtok.so.1
## CASA-auth-token-apache2_2-support ##
%pre -n CASA-auth-token-apache2_2-support
# Nothing to do in this pre script
%post -n CASA-auth-token-apache2_2-support
/sbin/ldconfig
%preun -n CASA-auth-token-apache2_2-support
# Nothing to do in this preun script
%postun -n CASA-auth-token-apache2_2-support
# Nothing to do in this postun script
%files -n CASA-auth-token-apache2_2-support
%defattr(-,root,root)
%{prefix}/%{_lib}/mod_authn_casa.so.%{bldno}
%{prefix}/%{_lib}/mod_authn_casa.so
%{prefix}/%{_lib}/mod_authn_casa.so.1
## CASA-auth-token-devel ##
%pre -n CASA-auth-token-devel
# Nothing to do in this pre script
%post -n CASA-auth-token-devel
# Nothing to do in this post script
%preun -n CASA-auth-token-devel
# Nothing to do in this preun script
%postun -n CASA-auth-token-devel
# Nothing to do in this postun script
%files -n CASA-auth-token-devel
%defattr(-,root,root)
%{prefix}/include/casa_c_authtoken.h
%{prefix}/include/casa_s_authtoken.h
%changelog -n package

View File

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

View File

@ -0,0 +1,37 @@
#######################################################################
#
# Copyright (C) 2006 Novell, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# Author: Juan Carlos Luciani <jluciani@novell.com>
#
#######################################################################
SUBDIRS = $(TARGET_OS)
DIST_SUBDIRS = linux
CFILES =
EXTRA_DIST = $(CFILES)
.PHONY: package package-clean package-install package-uninstall
package package-clean package-install package-uninstall:
$(MAKE) -C $(TARGET_OS) $@
maintainer-clean-local:
rm -f Makefile.in

View File

@ -0,0 +1,108 @@
/***********************************************************************
*
* README for mod_authn_casa
*
***********************************************************************/
INTRODUCTION
mod_authn_casa is an Apache 2.2 Basic Authentication Provider that
can be configured to validate Basic Credentials carrying CASA
Authentication Tokens.
Clients sending CASA Authentication Tokens as part of the Basic Credentials
will format them in the following manner: "username:CasaAuthenticationToken",
where the username is set to "CasaPrincipal" and the CasaAuthenticationToken
is the token string obtained from the CASA Get Authentication Token API..
CONFIGURATION
To use mod_authn_casa as an authentication provider for a specific location
you must first tell Apache that it must load the module, you do this by
placing the module or a link to the module in the Apache server's modules
folder and by placing the following line in the server's httpd.conf file:
LoadModule authn_casa_module modules/mod_authn_casa.so
The following lines show how Apache is configured to use mod_authn_casa
for authenticating requests issued to mod_example:
<Location /example-info>
SetHandler example-handler
AuthType Basic
AuthName "CASA-Authentication"
AuthBasicProvider casa
Require valid-user
</Location>
Note that the name specified in the AuthName directive should match the name
configured under CASA for the authentication realm used by CASA to obtain
identity information for the service.
mod_authn_casa supports the following configuration directives:
UsernameCheck - This is a per-directory or per-location directive which
configures whether or not mod_authn_casa must verify that
the username is set to "CasaPrincipal". Possible values
for this directive are 'on' or 'off'. Default is 'off'.
To enable UsernameChack for a particular location using
CASA Authentication, include the following line inside
the location configuration block:
UsernameCheck on
CLIENT PROGRAMMING NOTES
HTTP Clients sending requests to a location being protected by the CASA
Authentication Provider must obtain an Authentication Token from the CASA
Client for authenticating to the Service identified as the "location" being
accessed in the HTTP Server. In the case of mod_example, the service name
would be "example-info". Once the client obtains an Authentication Token
from the CASA Client it must then include it in the HTTP Basic Authentication
header that it must include in the HTTP Request. The HTTP Basic Authentication
credentials should be in the following form:
Base64("CasaPrincipal":"AuthenticationToken")
SERVER PROGRAMMING NOTES
Apache modules being protected by the CASA Authentication Provider can obtain
the following information about the authenticated identity:
username - This is accessed via the r->user variable or by examining the IdentityId
environment variable associated with the request block. The username is the
user's unique id within the authentication realm. When the authentication realm
is an LDAP database, the username consists of the user's fdn.
Name of the source of identity data (Authentication Realm) - This is accessed by
examining the IdentityDataSourceName environment variable associated with the
request block.
URL to the source of identity data - This is accessed by examining the
IdentityDataSourceUrl environment variable associated with the request block.
Attributes of the authenticated identity - The attributes are set as environment
variables associated with the request block. The environment variable names match
the names of the attributes. The attributes associated with the authenticated
identity and expressed as environment variables are configured at the time that
the service is enabled for CASA Authentication.
Note that environment variables are contained in the r->subprocess_env table.
SECURITY CONSIDERATIONS
CASA Authenticatication Tokens when compromised can be used to either impersonate
a user or to obtain identity information about the user. Because of this it is
important that the tokens be secured by applications making use of them. It is
recommended that the tokens be transmitted using HTTPS.

View File

@ -0,0 +1,13 @@
/***********************************************************************
*
* TODO for mod_authn_casa
*
***********************************************************************/
INTRODUCTION
This file contains a list of the items still outstanding for mod_authn_casa.
OUTSTANDING ITEMS
None.

View File

@ -0,0 +1,114 @@
#######################################################################
#
# Copyright (C) 2006 Novell, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# Author: Juan Carlos Luciani <jluciani@novell.com>
#
#######################################################################
if DEBUG
TARGET_CFG = Debug
CFLAGS += -v -w
else
TARGET_CFG = Release
endif
SUBDIRS =
DIST_SUBDIRS =
ROOT = ../../../..
LIBDIR = $(ROOT)/$(LIB)
APACHEINCLUDE = /usr/include/apache2
APACHELIB = /usr/lib/apache2
APRINCLUDE = /usr/include/apr-1
APRLIB = /usr/lib/apr-1
# handle Mono secondary dependencies
export MONO_PATH := $(MONO_PATH)
PLATFORMINDEPENDENTSOURCEDIR = ..
PLATFORMDEPENDENTSOURCEDIR = .
MODULE_NAME = mod_authn_casa
MODULE_EXT = so
CFILES = ../mod_authn_casa.c
CSFILES_CSC :=
INCLUDES = -I. -I$(ROOT)/include -I$(APACHEINCLUDE) -I$(APRINCLUDE)
RESOURCES =
DEFINES = -Wno-format-extra-args -fno-strict-aliasing
CFLAGS += $(INCLUDES) $(DEFINES) -D_LARGEFILE64_SOURCE
LIBS = -lpthread -lcasa_s_authtoken -lapr-1 -laprutil-1
LDFLAGS = -Bsymbolic -shared -Wl,-soname=$(MODULE_NAME).$(MODULE_EXT) -L$(LIBDIR)/$(TARGET_CFG) -L$(APACHELIB) -L$(APRLIB) -Xlinker -rpath -Xlinker /opt/novell/CASA/lib
OBJDIR = ./$(TARGET_CFG)/$(LIB)
OBJS = $(addprefix $(OBJDIR)/, $(CFILES:%.c=%.o))
EXTRA_DIST = $(CFILES)
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:
#cd $(TARGET_CFG); rm -rf *.dbg *.exe *.dll *.o *.so; cd ..; rmdir $(OBJDIR)
rm -rf $(TARGET_CFG)
distclean-local:
maintainer-clean-local:
rm -f Makefile.in

View File

@ -0,0 +1,478 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
#include <stdbool.h>
#include "apr_strings.h"
#include "ap_config.h"
#include "ap_provider.h"
#include "httpd.h"
#include "http_config.h"
#include "http_core.h"
#include "http_log.h"
#include "http_protocol.h"
#include "http_request.h"
#include "mod_auth.h"
#include "casa_s_authtoken.h"
//
// Module per-dir configuration structure.
//
typedef struct _authn_casa_dir_cfg
{
int performUsernameCheck;
} authn_casa_dir_cfg;
//
// Forward declaration of our module structure.
//
module AP_MODULE_DECLARE_DATA authn_casa_module;
//
// Environment variables set by module
//
static char CasaIdentityIdEnvVar[] = "IdentityId";
static char CasaIdentitySourceNameEnvVar[] = "IdentityDataSourceName";
static char CasaIdentitySourceUrlEnvVar[] = "IdentityDataSourceUrl";
//
// Function: create_per_dir_config()
//
// Create per-dir configuration structure.
//
static void*
create_per_dir_config(
apr_pool_t *p,
char *x)
{
authn_casa_dir_cfg *pDirConfig;
// Allocate space for our configuration structure
pDirConfig = (authn_casa_dir_cfg*) apr_palloc(p, sizeof(*pDirConfig));
// Return our new configuration structure
return (void*) pDirConfig;
}
/* ************************************************************************
* set_authn_casa_uname_check()
*
* Process UsernameCheck configuration directive..
*
* L2
* ************************************************************************/
static const char*
set_authn_casa_uname_check(
cmd_parms *cmd,
void *cfg,
int arg)
{
authn_casa_dir_cfg *pDirConfig = (authn_casa_dir_cfg*) cfg;
// Record the value in our structure
pDirConfig->performUsernameCheck = arg;
return NULL;
}
//
// Configuration directives array structure.
//
static const command_rec authn_casa_cmds[] =
{
AP_INIT_FLAG("UsernameCheck", // tbd - May be this directive should be on a per-directory or per-location basis
set_authn_casa_uname_check,
NULL,
OR_AUTHCFG,
"Check for username == CasaPrincipal (Value limited to 'on' or 'off')"),
{NULL}
};
/* ************************************************************************
* check_password()
*
* Given a user and password, expected to return AUTH_GRANTED if we
* can validate the user/password combination.
*
* L2
* ************************************************************************/
static authn_status
check_password(
request_rec *r,
const char *user,
const char *password)
{
authn_status retStatus;
authn_casa_dir_cfg *pDirConfig;
bool userNameChecked = false;
int i;
char *pLocationName;
// First determine the length of the name of the location being protected
i = 0;
while (r->uri[i] != '\0')
{
if (r->uri[i] == '/')
{
// Ignore the slash if it is at the beginning of the uri
if (i != 0)
{
// The slash is not at the beggining of the uri, stop.
break;
}
}
i++;
}
// Now get a copy of the location being protected
if (i > 1)
{
pLocationName = apr_palloc(r->pool, i);
if (pLocationName)
{
memset(pLocationName, 0, i);
memcpy(pLocationName, &(r->uri[1]), i - 1); // Do not include the slashes
}
else
{
ap_log_rerror(APLOG_MARK, APLOG_ALERT, 0, r, "Memory allocation failure");
return AUTH_GENERAL_ERROR;
}
}
else
{
// We are protecting the server root
pLocationName = "apache_root";
}
// Get access to our per-dir configuration structure
pDirConfig = ap_get_module_config(r->per_dir_config,
&authn_casa_module);
if (pDirConfig)
{
// Assume success
retStatus = AUTH_GRANTED;
// Check if we must perform the username check
if (pDirConfig->performUsernameCheck != 0)
{
// Remember that we performed this check
userNameChecked = true;
// Check if the username matches the name what we are expecting
if (strcmp(user, "CasaPrincipal") != 0)
{
// The username does not match, allow other providers to get
// a crack to it.
retStatus = AUTH_USER_NOT_FOUND;
}
}
// Check the token if a problem has not been found
if (retStatus == AUTH_GRANTED)
{
CasaStatus casaStatus;
PrincipalIf *pPrincipalIf;
// Validate the token
casaStatus = ValidateAuthToken(pLocationName,
password,
strlen(password),
&pPrincipalIf);
if (CASA_SUCCESS(casaStatus))
{
int buffLen = 0;
apr_table_t *e = r->subprocess_env;
// Associate necessary environment variables with the request block
casaStatus = pPrincipalIf->getIdentityId(pPrincipalIf,
NULL,
&buffLen);
if (CasaStatusCode(casaStatus) == CASA_STATUS_BUFFER_OVERFLOW)
{
char *pBuff;
// Allocate buffer to obtain the Identity Id
pBuff = apr_pcalloc(r->pool, buffLen);
if (pBuff)
{
// Read the value into our buffer
if (CASA_SUCCESS(pPrincipalIf->getIdentityId(pPrincipalIf,
pBuff,
&buffLen)))
{
// Now set the environment variable
apr_table_setn(e, CasaIdentityIdEnvVar, pBuff);
// Also, update the username within the request block with the identity id
r->user = pBuff;
}
else
{
ap_log_rerror(APLOG_MARK, APLOG_ALERT, 0, r, "Unable to obtain identity id");
retStatus = AUTH_GENERAL_ERROR;
}
}
else
{
ap_log_rerror(APLOG_MARK, APLOG_ALERT, 0, r, "Memory allocation failure");
retStatus = AUTH_GENERAL_ERROR;
}
}
else
{
ap_log_rerror(APLOG_MARK, APLOG_ALERT, 0, r, "Un-expected error obtaining identity id, %08X", casaStatus);
retStatus = AUTH_GENERAL_ERROR;
}
if (retStatus == AUTH_GRANTED)
{
buffLen = 0;
casaStatus = pPrincipalIf->getSourceName(pPrincipalIf,
NULL,
&buffLen);
if (CasaStatusCode(casaStatus) == CASA_STATUS_BUFFER_OVERFLOW)
{
char *pBuff;
// Allocate buffer to obtain the Identity Source Name
pBuff = apr_pcalloc(r->pool, buffLen);
if (pBuff)
{
// Read the value into our buffer
if (CASA_SUCCESS(pPrincipalIf->getSourceName(pPrincipalIf,
pBuff,
&buffLen)))
{
// Now set the environment variable
apr_table_setn(e, CasaIdentitySourceNameEnvVar, pBuff);
}
else
{
ap_log_rerror(APLOG_MARK, APLOG_ALERT, 0, r, "Unable to obtain identity source name");
retStatus = AUTH_GENERAL_ERROR;
}
}
else
{
ap_log_rerror(APLOG_MARK, APLOG_ALERT, 0, r, "Memory allocation failure");
retStatus = AUTH_GENERAL_ERROR;
}
}
else
{
ap_log_rerror(APLOG_MARK, APLOG_ALERT, 0, r, "Un-expected error obtaining identity source name, %08X", casaStatus);
retStatus = AUTH_GENERAL_ERROR;
}
}
if (retStatus == AUTH_GRANTED)
{
buffLen = 0;
casaStatus = pPrincipalIf->getSourceUrl(pPrincipalIf,
NULL,
&buffLen);
if (CasaStatusCode(casaStatus) == CASA_STATUS_BUFFER_OVERFLOW)
{
char *pBuff;
// Allocate buffer to obtain the Identity Source Url
pBuff = apr_pcalloc(r->pool, buffLen);
if (pBuff)
{
// Read the value into our buffer
if (CASA_SUCCESS(pPrincipalIf->getSourceUrl(pPrincipalIf,
pBuff,
&buffLen)))
{
// Now set the environment variable
apr_table_setn(e, CasaIdentitySourceUrlEnvVar, pBuff);
}
else
{
ap_log_rerror(APLOG_MARK, APLOG_ALERT, 0, r, "Unable to obtain identity source url");
retStatus = AUTH_GENERAL_ERROR;
}
}
else
{
ap_log_rerror(APLOG_MARK, APLOG_ALERT, 0, r, "Memory allocation failure");
retStatus = AUTH_GENERAL_ERROR;
}
}
else
{
ap_log_rerror(APLOG_MARK, APLOG_ALERT, 0, r, "Un-expected error obtaining identity source url, %08X", casaStatus);
retStatus = AUTH_GENERAL_ERROR;
}
}
if (retStatus == AUTH_GRANTED)
{
char *pAttribNameBuff, *pAttribValueBuff;
int enumHandle = 0;
int attribNameBuffLen, attribValueBuffLen;
while (retStatus == AUTH_GRANTED)
{
// Get attribute lengths
attribNameBuffLen = attribValueBuffLen = 0;
casaStatus = pPrincipalIf->attributeEnumerate(pPrincipalIf,
&enumHandle,
NULL,
&attribNameBuffLen,
NULL,
&attribValueBuffLen);
if (CasaStatusCode(casaStatus) == CASA_STATUS_BUFFER_OVERFLOW)
{
// Allocate buffers to obtain the attribute data
pAttribNameBuff = apr_pcalloc(r->pool, attribNameBuffLen);
pAttribValueBuff = apr_pcalloc(r->pool, attribValueBuffLen);
if (pAttribNameBuff && pAttribValueBuff)
{
// Read the attribute into our buffer
if (CASA_SUCCESS(pPrincipalIf->attributeEnumerate(pPrincipalIf,
&enumHandle,
pAttribNameBuff,
&attribNameBuffLen,
pAttribValueBuff,
&attribValueBuffLen)))
{
// Now set the environment variable
apr_table_setn(e, pAttribNameBuff, pAttribValueBuff);
}
else
{
ap_log_rerror(APLOG_MARK, APLOG_ALERT, 0, r, "Unable to obtain identity attribute");
retStatus = AUTH_GENERAL_ERROR;
}
}
else
{
ap_log_rerror(APLOG_MARK, APLOG_ALERT, 0, r, "Memory allocation failure");
retStatus = AUTH_GENERAL_ERROR;
}
}
else
{
// Check if we are done going through the attributes
if (CasaStatusCode(casaStatus) == CASA_STATUS_NO_MORE_ENTRIES)
{
// Done
break;
}
else
{
ap_log_rerror(APLOG_MARK, APLOG_ALERT, 0, r, "Un-expected error during attribute enumeration, %08X", casaStatus);
retStatus = AUTH_GENERAL_ERROR;
}
}
}
}
// Release the principal interface instance
pPrincipalIf->releaseReference(pPrincipalIf);
}
else
{
// Check if the token validation failed for a CasaPrincipal
if (userNameChecked)
{
// Token validation failed for a CasaPrincipal, always return AUTH_DENIED.
retStatus = AUTH_DENIED;
}
else
{
// We did not check the username, set the return status based on the status
// returned by ValidateAuthToken().
if (CasaStatusCode(casaStatus) == CASA_STATUS_AUTHENTICATION_FAILURE)
{
// Authentication failed
retStatus = AUTH_DENIED;
}
else
{
// Allow other providers to get a crack to it
retStatus = AUTH_USER_NOT_FOUND;
}
}
}
}
}
else
{
ap_log_rerror(APLOG_MARK, APLOG_ALERT, 0, r, "Did not get module per-server config structure");
retStatus = AUTH_GENERAL_ERROR;
}
return retStatus;
}
//
// Authentication Provider Function Table
//
static const authn_provider authn_casa_provider =
{
&check_password,
NULL, // We do not support Digest Authentication
};
/* ************************************************************************
* register_hooks()
*
* Register all of the module hooks.
*
* L2
* ************************************************************************/
static void
register_hooks(
apr_pool_t *p)
{
// Register as an authentication provider
ap_register_provider(p,
AUTHN_PROVIDER_GROUP, // Provider group
"casa", // Provider name
"0", // Provider version
&authn_casa_provider); // Authentication Provider function table
}
//
// Declare ourselves to the HTTPD core.
//
module AP_MODULE_DECLARE_DATA authn_casa_module =
{
STANDARD20_MODULE_STUFF,
create_per_dir_config, // Create per-dir config structures
NULL, // merge per-dir config structures
NULL, // Create per-server config structures
NULL, // merge per-server config structures
authn_casa_cmds, // command handlers
register_hooks // register hooks
};

View File

@ -0,0 +1,37 @@
#######################################################################
#
# Copyright (C) 2006 Novell, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# Author: Juan Carlos Luciani <jluciani@novell.com>
#
#######################################################################
SUBDIRS = 2.2
DIST_SUBDIRS = 2.2
CFILES =
EXTRA_DIST = $(CFILES)
.PHONY: package package-clean package-install package-uninstall
package package-clean package-install package-uninstall:
$(MAKE) -C $(TARGET_OS) $@
maintainer-clean-local:
rm -f Makefile.in

View File

@ -0,0 +1,37 @@
#######################################################################
#
# Copyright (C) 2006 Novell, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# Author: Juan Carlos Luciani <jluciani@novell.com>
#
#######################################################################
SUBDIRS = $(TARGET_OS) idenTokenProviders
DIST_SUBDIRS = linux idenTokenProviders
CFILES =
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

View File

@ -0,0 +1,77 @@
/***********************************************************************
*
* README for libcasa_s_authtoken
*
***********************************************************************/
INTRODUCTION
libcasa_s_authtoken provides an API for the validation of CASA Authentication Tokens.
The API provides a means for obtaining identity information about authenticated
entities.
Applications should avoid calling directly into this library's APIs. Instead, applications
should code to the PAM API to validate authentication credentials or allow an external
module to perform the credential validation. To facilitate this, CASA Authentication
provides PAM, Apache, and JAAS modules that can be used to validate credentials containing
CASA Authentication tokens,
CONFIGURING TRUSTED AUTHENTICATION TOKEN SERVICES
tbd. Add info about the installation of public certificates and trusted certificate authorities.
CONFIGURING ADDITIONAL IDENTITY TOKEN PROVIDER MODULES
CASA Authentication Tokens contain Identity Tokens. The Identity Tokens contain the identity
information about the entity being authenticated. Identity Tokens can be of different types,
the type utilized for use with a particular service is configured at the time that the service
is configured for CASA Authentication. The default identity token type is CasaIdentityToken.
libcasa_s_authtoken supports different identity token types through an API that allows for the
configuration of different Identity Token Provider plug-ins. An Identity Token Provider plug-in
is configured by placing a configuration file for the plug-ins in the
/etc/opt/CASA/authtoken.d/modules.d folder. The name of the plug-in configuration file is related
to the identity token type in the following manner: IdentityTokenTypeName.conf.
Identity Token Provider plug-in configuration files must must contain a directive indicating the
path to the library implementing the Identity Token Provider plug-in (See the configuration file
for the CasaIdentityToken plug-in for an example).
SERVER APPLICATION PROGRAMMING NOTES
The Validate CASA Authentication Token API is defined in casa_s_authtoken.h.
The API consists of a call to validate authentication tokens. The caller must supply a service
name which must match the service name provided by the client when requesting the authentication
token. Successful calls to the validate authentication token API will return a handle to a principal
interface object. The principal interface object handle can be used to obtain identity information
about the authenticated entity as well as information about the authentication realm. The principal
interface object must be released after it is no longer needed. The amount and type of identity
information associated with the principal interface is dependent on what is configured at the
time that the service is enabled for CASA Authentication.
For examples of code which uses the Validate CASA Authentication Token API look at the implementations
of the CASA Authentication PAM module and the CASA Authentication Provider Apache module.
IDENTITY TOKEN PROVIDER PROGRAMMING NOTES
The Identity Token Provider API is defined in iden_token_provider.h.
For an example see the implementation of the CASA Identity Token Provider.
SECURITY CONSIDERATIONS
CASA Authentication Tokens when compromised can be used to either impersonate
a user or to obtain identity information about the user. Because of this it is
important that the tokens be secured by applications making use of them. It is
recommended that the tokens be transmitted using SSL.

View File

@ -0,0 +1,15 @@
/***********************************************************************
*
* TODO for libcasa_s_authtoken
*
***********************************************************************/
INTRODUCTION
This file contains a list of the items still outstanding for libcasa_s_authtoken.
OUTSTANDING ITEMS
- Change AuthTokens to be SOAP messages secured with WS-Security and WS-Trust.
- Implement CheckAuthToken().
- Finish README documentation.

View File

@ -0,0 +1,693 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
//===[ Include files ]=====================================================
#include "internal.h"
//===[ Type definitions ]==================================================
//
// Parse states
//
#define AWAITING_ROOT_ELEMENT_START 0x0
#define AWAITING_ROOT_ELEMENT_END 0x1
#define AWAITING_SIGNATURE_DATA 0x2
#define AWAITING_SIGNATURE_ELEMENT_START 0x3
#define AWAITING_SIGNATURE_ELEMENT_END 0x4
#define AWAITING_LIFETIME_DATA 0x5
#define AWAITING_LIFETIME_ELEMENT_START 0x6
#define AWAITING_LIFETIME_ELEMENT_END 0x7
#define AWAITING_IDENT_TOKEN_ELEMENT_START 0x8
#define AWAITING_IDENT_TOKEN_ELEMENT_END 0x9
#define AWAITING_IDENT_TOKEN_DATA 0xA
#define AWAITING_TYPE_ELEMENT_START 0xB
#define AWAITING_TYPE_ELEMENT_END 0xC
#define AWAITING_TYPE_DATA 0xD
#define DONE_PARSING 0xE
//
// Authentication Token Parse Structure
//
typedef struct _AuthTokenParse
{
XML_Parser p;
int state;
int elementDataProcessed;
AuthToken *pAuthToken;
CasaStatus status;
} AuthTokenParse, *PAuthTokenParse;
//===[ Function prototypes ]===============================================
//===[ Global variables ]==================================================
//++=======================================================================
static
void XMLCALL
AuthTokenStartElementHandler(
IN void *pUserData,
IN const XML_Char *name,
IN const XML_Char **atts)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// L2
//=======================================================================--
{
AuthTokenParse *pAuthTokenParse = (AuthTokenParse*) pUserData;
DbgTrace(2, "-AuthTokenStartElementHandler- Start\n", 0);
// Proceed based on the state
switch (pAuthTokenParse->state)
{
case AWAITING_ROOT_ELEMENT_START:
// In this state, we are only expecting the Authentication
// Response Element.
if (strcmp(name, AUTH_TOKEN_ELEMENT_NAME) == 0)
{
// Good, advance to the next state.
pAuthTokenParse->state = AWAITING_SIGNATURE_ELEMENT_START;
}
else
{
DbgTrace(0, "-AuthTokenStartElementHandler- Un-expected start element\n", 0);
XML_StopParser(pAuthTokenParse->p, XML_FALSE);
}
break;
case AWAITING_SIGNATURE_ELEMENT_START:
// In this state, we are only expecting the Signature Element.
if (strcmp(name, SIGNATURE_ELEMENT_NAME) == 0)
{
// Good, advance to the next state.
pAuthTokenParse->state = AWAITING_SIGNATURE_DATA;
}
else
{
DbgTrace(0, "-AuthTokenStartElementHandler- Un-expected start element\n", 0);
XML_StopParser(pAuthTokenParse->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.
pAuthTokenParse->state = AWAITING_LIFETIME_DATA;
}
else
{
DbgTrace(0, "-AuthTokenStartElementHandler- Un-expected start element\n", 0);
XML_StopParser(pAuthTokenParse->p, XML_FALSE);
}
break;
case AWAITING_IDENT_TOKEN_ELEMENT_START:
// In this state, we are only expecting the Identity Token Element.
if (strcmp(name, IDENTITY_TOKEN_ELEMENT_NAME) == 0)
{
// Good, advance to the next state.
pAuthTokenParse->state = AWAITING_TYPE_ELEMENT_START;
}
else
{
DbgTrace(0, "-AuthTokenStartElementHandler- Un-expected start element\n", 0);
XML_StopParser(pAuthTokenParse->p, XML_FALSE);
}
break;
case AWAITING_TYPE_ELEMENT_START:
// In this state, we are only expecting the Type Element.
if (strcmp(name, TYPE_ELEMENT_NAME) == 0)
{
// Good, advance to the next state.
pAuthTokenParse->state = AWAITING_TYPE_DATA;
}
else
{
DbgTrace(0, "-AuthTokenStartElementHandler- Un-expected start element\n", 0);
XML_StopParser(pAuthTokenParse->p, XML_FALSE);
}
break;
default:
DbgTrace(0, "-AuthTokenStartElementHandler- Un-expected state = %d\n", pAuthTokenParse->state);
XML_StopParser(pAuthTokenParse->p, XML_FALSE);
break;
}
DbgTrace(2, "-AuthTokenStartElementHandler- End\n", 0);
}
//++=======================================================================
static
CasaStatus
ConsumeElementData(
IN AuthTokenParse *pAuthTokenParse,
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
pAuthTokenParse->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 = pAuthTokenParse->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(pAuthTokenParse->elementDataProcessed + len + 1);
if (pNewBuf)
{
memset(pNewBuf,
0,
pAuthTokenParse->elementDataProcessed + len + 1);
memcpy(pNewBuf,
*ppElementData,
pAuthTokenParse->elementDataProcessed);
memcpy(pNewBuf + pAuthTokenParse->elementDataProcessed, s, len);
pAuthTokenParse->elementDataProcessed += len;
// Swap the buffers
free(*ppElementData);
*ppElementData = pNewBuf;
// Return the length of the element data buffer
*pElementDataLen = pAuthTokenParse->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
AuthTokenCharDataHandler(
IN void *pUserData,
IN const XML_Char *s,
IN int len)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// L2
//=======================================================================--
{
AuthTokenParse *pAuthTokenParse = (AuthTokenParse*) pUserData;
DbgTrace(2, "-AuthTokenCharDataHandler- Start\n", 0);
// Just exit if being called to process LF and CR characters
if (len == 1
&& ((*s == '\n') || (*s == '\r')))
{
goto exit;
}
// Proceed based on the state
switch (pAuthTokenParse->state)
{
case AWAITING_SIGNATURE_DATA:
case AWAITING_SIGNATURE_ELEMENT_END:
pAuthTokenParse->status = ConsumeElementData(pAuthTokenParse,
s,
len,
&pAuthTokenParse->pAuthToken->pSignature,
&pAuthTokenParse->pAuthToken->signatureLen);
if (CASA_SUCCESS(pAuthTokenParse->status))
{
// Advanced to the next state
pAuthTokenParse->state = AWAITING_SIGNATURE_ELEMENT_END;
}
else
{
XML_StopParser(pAuthTokenParse->p, XML_FALSE);
}
break;
case AWAITING_LIFETIME_DATA:
case AWAITING_LIFETIME_ELEMENT_END:
// Convert the lifetime string to a numeric value
pAuthTokenParse->pAuthToken->tokenLifetime = dtoul((char*) s, len);
// Advanced to the next state
pAuthTokenParse->state = AWAITING_LIFETIME_ELEMENT_END;
break;
case AWAITING_TYPE_DATA:
case AWAITING_TYPE_ELEMENT_END:
pAuthTokenParse->status = ConsumeElementData(pAuthTokenParse,
s,
len,
&pAuthTokenParse->pAuthToken->pIdenTokenType,
&pAuthTokenParse->pAuthToken->idenTokenTypeLen);
if (CASA_SUCCESS(pAuthTokenParse->status))
{
// Advanced to the next state
pAuthTokenParse->state = AWAITING_TYPE_ELEMENT_END;
}
else
{
XML_StopParser(pAuthTokenParse->p, XML_FALSE);
}
break;
case AWAITING_IDENT_TOKEN_DATA:
case AWAITING_IDENT_TOKEN_ELEMENT_END:
pAuthTokenParse->status = ConsumeElementData(pAuthTokenParse,
s,
len,
&pAuthTokenParse->pAuthToken->pIdenToken,
&pAuthTokenParse->pAuthToken->idenTokenLen);
if (CASA_SUCCESS(pAuthTokenParse->status))
{
// Advanced to the next state
pAuthTokenParse->state = AWAITING_IDENT_TOKEN_ELEMENT_END;
}
else
{
XML_StopParser(pAuthTokenParse->p, XML_FALSE);
}
break;
default:
DbgTrace(0, "-AuthTokenCharDataHandler- Un-expected state = %d\n", pAuthTokenParse->state);
XML_StopParser(pAuthTokenParse->p, XML_FALSE);
break;
}
exit:
DbgTrace(2, "-AuthTokenCharDataHandler- End\n", 0);
}
//++=======================================================================
static
void XMLCALL
AuthTokenEndElementHandler(
IN void *pUserData,
IN const XML_Char *name)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// L2
//=======================================================================--
{
AuthTokenParse *pAuthTokenParse = (AuthTokenParse*) pUserData;
DbgTrace(2, "-AuthTokenEndElementHandler- Start\n", 0);
// Proceed based on the state
switch (pAuthTokenParse->state)
{
case AWAITING_ROOT_ELEMENT_END:
// In this state, we are only expecting the Authentication
// Token Element.
if (strcmp(name, AUTH_TOKEN_ELEMENT_NAME) == 0)
{
// Done.
pAuthTokenParse->state = DONE_PARSING;
}
else
{
DbgTrace(0, "-AuthTokenEndHandler- Un-expected end element\n", 0);
XML_StopParser(pAuthTokenParse->p, XML_FALSE);
}
break;
case AWAITING_SIGNATURE_ELEMENT_END:
// In this state, we are only expecting the Signature Element.
if (strcmp(name, SIGNATURE_ELEMENT_NAME) == 0)
{
// Good, advance to the next state.
pAuthTokenParse->state = AWAITING_LIFETIME_ELEMENT_START;
}
else
{
DbgTrace(0, "-AuthTokenEndElementHandler- Un-expected end element\n", 0);
XML_StopParser(pAuthTokenParse->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.
pAuthTokenParse->state = AWAITING_IDENT_TOKEN_ELEMENT_START;
}
else
{
DbgTrace(0, "-AuthTokenEndElementHandler- Un-expected end element\n", 0);
XML_StopParser(pAuthTokenParse->p, XML_FALSE);
}
break;
case AWAITING_TYPE_ELEMENT_END:
// In this state, we are only expecting the Type Element.
if (strcmp(name, TYPE_ELEMENT_NAME) == 0)
{
// Good, advance to the next state.
pAuthTokenParse->state = AWAITING_IDENT_TOKEN_DATA;
}
else
{
DbgTrace(0, "-AuthTokenEndElementHandler- Un-expected end element\n", 0);
XML_StopParser(pAuthTokenParse->p, XML_FALSE);
}
break;
case AWAITING_IDENT_TOKEN_ELEMENT_END:
// In this state, we are only expecting the Identity Token Element.
if (strcmp(name, IDENTITY_TOKEN_ELEMENT_NAME) == 0)
{
// Good, advance to the next state.
pAuthTokenParse->state = AWAITING_ROOT_ELEMENT_END;
}
else
{
DbgTrace(0, "-AuthTokenEndElementHandler- Un-expected end element\n", 0);
XML_StopParser(pAuthTokenParse->p, XML_FALSE);
}
break;
default:
DbgTrace(0, "-AuthTokenEndElementHandler- Un-expected state = %d\n", pAuthTokenParse->state);
XML_StopParser(pAuthTokenParse->p, XML_FALSE);
break;
}
DbgTrace(2, "-AuthTokenEndElementHandler- End\n", 0);
}
//++=======================================================================
CasaStatus
CreateAuthToken(
IN char *pTokenBuf,
IN int tokenBufLen,
INOUT AuthToken **ppAuthToken)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// L2
//=======================================================================--
{
CasaStatus retStatus = CASA_STATUS_SUCCESS;
AuthTokenParse authTokenParse = {0};
AuthToken *pAuthToken;
DbgTrace(1, "-CreateAuthToken- Start\n", 0);
/*
* Authentication tokens have the following format:
*
* <?xml version="1.0" encoding="ISO-8859-1"?>
* <auth_token>
* <signature>signature value</signature>
* <lifetime>lifetime value</lifetime>
* <ident_token><type>identity token type</type>identity token data</ident_token>
* </auth_token>
*
*/
// Allocate AuthToken object
pAuthToken = malloc(sizeof(*pAuthToken));
if (pAuthToken)
{
XML_Parser p;
// Initialize the AuthToken object and set it in the
// authentication response parse object.
memset(pAuthToken, 0, sizeof(*pAuthToken));
authTokenParse.pAuthToken = pAuthToken;
// Create parser
p = XML_ParserCreate(NULL);
if (p)
{
// Keep track of the parser in our parse object
authTokenParse.p = p;
// Initialize the status within the parse object
authTokenParse.status = CASA_STATUS_SUCCESS;
// Set the start and end element handlers
XML_SetElementHandler(p,
AuthTokenStartElementHandler,
AuthTokenEndElementHandler);
// Set the character data handler
XML_SetCharacterDataHandler(p, AuthTokenCharDataHandler);
// Set our user data
XML_SetUserData(p, &authTokenParse);
// Parse the document
if (XML_Parse(p, pTokenBuf, tokenBufLen, 1) == XML_STATUS_OK)
{
// Verify that the parse operation completed successfully
if (authTokenParse.state == DONE_PARSING)
{
// The parse operation succeded.
retStatus = CASA_STATUS_SUCCESS;
}
else
{
DbgTrace(0, "-CreateAuthToken- Parse operation did not complete\n", 0);
// Check if a status has been recorded
if (authTokenParse.status != CASA_STATUS_SUCCESS)
{
retStatus = authTokenParse.status;
}
else
{
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_PROTOCOL_ERROR);
}
}
}
else
{
DbgTrace(0, "-CreateAuthToken- 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, "-CreateAuthToken- 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))
{
*ppAuthToken = pAuthToken;
}
else
{
free(pAuthToken);
}
}
else
{
DbgTrace(0, "-CreateAuthToken- Memory allocation error\n", 0);
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_INSUFFICIENT_RESOURCES);
}
DbgTrace(1, "-CreateAuthToken- End, retStatus = %08X\n", retStatus);
return retStatus;
}
//++=======================================================================
void
RelAuthToken(
IN AuthToken *pAuthToken)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// L2
//=======================================================================--
{
DbgTrace(1, "-RelAuthToken- Start\n", 0);
// Free the resources associated with the object
if (pAuthToken->pSignature)
free(pAuthToken->pSignature);
if (pAuthToken->pIdenTokenType)
free(pAuthToken->pIdenTokenType);
if (pAuthToken->pIdenToken)
free(pAuthToken->pIdenToken);
free(pAuthToken);
DbgTrace(1, "-RelAuthToken- End\n", 0);
}
//++=======================================================================
CasaStatus
CheckAuthToken(
IN AuthToken *pAuthToken,
IN const char *pServiceName)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// L0
//=======================================================================--
{
CasaStatus retStatus = CASA_STATUS_SUCCESS;
DbgTrace(1, "-CheckuthToken- Start\n", 0);
// tbd
DbgTrace(1, "-CheckAuthToken- End, retStatus = %08X\n", retStatus);
return retStatus;
}

View File

@ -0,0 +1,764 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
//===[ 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;
// Synchronization mutex
static
HANDLE g_configIfMutex = NULL;
//++=======================================================================
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);
}
//++=======================================================================
static
int SSCS_CALL
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, "-AddReference- Start\n", 0);
// Increment the reference count on the object
PlatAcquireMutex(g_configIfMutex);
pConfigIfInstance->refCount ++;
refCount = pConfigIfInstance->refCount;
PlatReleaseMutex(g_configIfMutex);
DbgTrace(2, "-AddReference- End, refCount = %08X\n", refCount);
return refCount;
}
//++=======================================================================
static
void SSCS_CALL
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, "-ReleaseReference- Start\n", 0);
// Decrement the reference count on the object and determine if it needs to
// be released.
PlatAcquireMutex(g_configIfMutex);
pConfigIfInstance->refCount --;
if (pConfigIfInstance->refCount == 0)
{
// The object needs to be released, forget about it.
freeObj = true;
g_numConfigIfObjs --;
RemoveEntryList(&pConfigIfInstance->listEntry);
}
PlatReleaseMutex(g_configIfMutex);
// 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, "-ReleaseReference- End\n", 0);
}
//++=======================================================================
static
char* SSCS_CALL
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 = strlen(pKeyName);
char *pKeyNameLowercase;
DbgTrace(2, "-GetEntryValue- Start\n", 0);
// Allocate enough space to hold lower case version of the key name
pKeyNameLowercase = 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 = malloc(pConfigKey->valueLen + 1);
if (pValue)
{
strcpy(pValue, pConfigKey->pValue);
}
else
{
DbgTrace(0, "-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, "-GetEntryValue- Buffer allocation failure\n", 0);
}
DbgTrace(2, "-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 = strlen(pConfigFolder);
int configNameLen = 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);
PlatAcquireMutex(g_configIfMutex);
// 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 = malloc(configFolderLen + 1 + configNameLen + sizeof(".conf"));
if (pFilePath)
{
FILE *pConfigFile;
strcpy(pFilePath, pConfigFolder);
strcat(pFilePath, "/");
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 = 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 = AddReference;
pConfigIfInstance->configIf.releaseReference = ReleaseReference;
pConfigIfInstance->configIf.getEntryValue = GetEntryValue;
// Save the ConfigFolder and ConfigName information within the instance data
pConfigIfInstance->pConfigFolder = malloc(configFolderLen + 1);
if (pConfigIfInstance->pConfigFolder)
{
strcpy(pConfigIfInstance->pConfigFolder, pConfigFolder);
pConfigIfInstance->configFolderLen = configFolderLen;
pConfigIfInstance->pConfigName = 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 = 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 = malloc(sizeof(*pConfigKey));
if (pConfigKey)
{
pConfigKey->keyNameLen = strlen(pKey);
pConfigKey->pKeyName = malloc(pConfigKey->keyNameLen + 1);
if (pConfigKey->pKeyName)
{
// Save the key name in lower case
LowerCaseString(pConfigKey->pKeyName, pKey);
pConfigKey->valueLen = strlen(pValue);
pConfigKey->pValue = 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(1, "-GetConfigInterface- Unable to open config file, errno = %d\n", errno);
}
}
else
{
DbgTrace(0, "-GetConfigInterface- Buffer allocation error\n", 0);
}
}
PlatReleaseMutex(g_configIfMutex);
DbgTrace(2, "-GetConfigInterface- End, retStatus = %08X\n", retStatus);
return retStatus;
}
//++=======================================================================
CasaStatus
ConfigIfInit(void)
//
// Arguments:
//
// Returns:
// Casa Status
//
// Description:
// Initializes the configuration interface complex.
//
// L2
//=======================================================================--
{
CasaStatus retStatus;
DbgTrace(1, "-ConfigIfInit- Start\n", 0);
// Allocate mutex
if ((g_configIfMutex = PlatAllocMutex()) != NULL)
retStatus = CASA_STATUS_SUCCESS;
else
retStatus = CasaStatusBuild(CASA_SEVERITY_INFORMATIONAL,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_INSUFFICIENT_RESOURCES);
DbgTrace(1, "-ConfigIfInit- End, retStatus = %08X\n", retStatus);
return retStatus;
}
//++=======================================================================
void
ConfigIfUninit(void)
//
// Arguments:
//
// Returns:
// Casa Status
//
// Description:
// Uninitializes the configuration interface complex.
//
// L2
//=======================================================================--
{
DbgTrace(1, "-ConfigIfUninit- Start\n", 0);
// Free mutex if necessary
if (g_configIfMutex)
{
PlatDestroyMutex(g_configIfMutex);
g_configIfMutex = NULL;
}
DbgTrace(1, "-ConfigIfUninit- End\n", 0);
}
//++=======================================================================
//++=======================================================================
//++=======================================================================

View File

@ -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 <jluciani@novell.com>
*
***********************************************************************/
#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_

View File

@ -0,0 +1,37 @@
#######################################################################
#
# Copyright (C) 2006 Novell, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# Author: Juan Carlos Luciani <jluciani@novell.com>
#
#######################################################################
SUBDIRS = casa
DIST_SUBDIRS = casa
CFILES =
EXTRA_DIST = $(CFILES)
.PHONY: package package-clean package-install package-uninstall
package package-clean package-install package-uninstall:
$(MAKE) -C $(TARGET_OS) $@
maintainer-clean-local:
rm -f Makefile.in

View File

@ -0,0 +1,37 @@
#######################################################################
#
# Copyright (C) 2006 Novell, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# Author: Juan Carlos Luciani <jluciani@novell.com>
#
#######################################################################
SUBDIRS = $(TARGET_OS)
DIST_SUBDIRS = linux
CFILES =
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

View File

@ -0,0 +1,39 @@
/***********************************************************************
*
* README for casa_identoken
*
***********************************************************************/
INTRODUCTION
casa_identoken is the Identity Token Provider plug-in for tokens of type
CasaIdentityToken. This are the default identity tokens utilized by CASA
Authentication.
CONFIGURATION
The path to the casa_identoken plug-in is configured by placing the file
CasaIdentityToken.conf in the /etc/opt/CASA/authtoken.d/modules.d folder.
PROGRAMMING NOTES
This module does not provide APIs to components outside of the CASA
Authentication framework.
SECURITY CONSIDERATIONS
CasaIdentityTokens are embedded inside CASA Authentication Tokens. CasaIdentityTokens
contain identity information which may be confidential and no attempts are made to
ensure the confidentiality of the data. Because of this it is important that CASA
Authentication Tokens be secured by applications making use of them. It is recommended
that CASA authentication tokens be transmitted using SSL.

View File

@ -0,0 +1,13 @@
/***********************************************************************
*
* TODO for casa_identoken
*
***********************************************************************/
INTRODUCTION
This file contains a list of the items still outstanding for casa_identoken.
OUTSTANDING ITEMS
None.

View File

@ -0,0 +1,346 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
//===[ Include files ]=====================================================
#include "internal.h"
//===[ Type definitions ]==================================================
//
// Identity Token Provider Interface instance data
//
typedef struct _IdenTokenProviderIfInstance
{
int refCount;
IdenTokenProviderIf idenTokenProviderIf;
} IdenTokenProviderIfInstance, *PIdenTokenProviderIfInstance;
//===[ Function prototypes ]===============================================
//===[ Global variables ]==================================================
// IdenTokenProviderIf variables
static
int g_numIdenTokenProviderIfObjs = 0;
// Debug Level
int DebugLevel = 0;
//
// Initialization variables
//
static
bool g_moduleInitialized = false;
// Synchronization mutex
static
HANDLE g_idenTokenProviderIfMutex = NULL;
//++=======================================================================
static
int SSCS_CALL
AddReference(
IN const void *pIfInstance)
//
// Arguments:
// pIfInstance -
// Pointer to interface object.
//
// Returns:
// Interface reference count.
//
// Description:
// Increases interface reference count.
//
// L2
//=======================================================================--
{
int refCount;
IdenTokenProviderIfInstance *pIdenTokenProviderIfInstance = CONTAINING_RECORD(pIfInstance, IdenTokenProviderIfInstance, idenTokenProviderIf);
DbgTrace(2, "-AddReference- Start\n", 0);
// Increment the reference count on the object
PlatAcquireMutex(g_idenTokenProviderIfMutex);
pIdenTokenProviderIfInstance->refCount ++;
refCount = pIdenTokenProviderIfInstance->refCount;
PlatReleaseMutex(g_idenTokenProviderIfMutex);
DbgTrace(2, "-AddReference- End, refCount = %08X\n", refCount);
return refCount;
}
//++=======================================================================
static
void SSCS_CALL
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;
IdenTokenProviderIfInstance *pIdenTokenProviderIfInstance = CONTAINING_RECORD(pIfInstance, IdenTokenProviderIfInstance, idenTokenProviderIf);
DbgTrace(2, "-ReleaseReference- Start\n", 0);
// Decrement the reference count on the object and determine if it needs to
// be released.
PlatAcquireMutex(g_idenTokenProviderIfMutex);
pIdenTokenProviderIfInstance->refCount --;
if (pIdenTokenProviderIfInstance->refCount == 0)
{
// The object needs to be released, forget about it.
freeObj = true;
g_numIdenTokenProviderIfObjs --;
}
PlatReleaseMutex(g_idenTokenProviderIfMutex);
// Free object if necessary
if (freeObj)
free(pIdenTokenProviderIfInstance);
DbgTrace(2, "-ReleaseReference- End\n", 0);
}
//++=======================================================================
static
CasaStatus
GetIdentityTokenIf(
IN const void *pIfInstance,
IN const char *pTokenBuf,
IN const int tokenLen,
INOUT IdenTokenIf **ppIdenTokenIf)
//
// Arguments:
// pIfInstance -
// Pointer to interface object.
//
// pTokenBuf -
// Pointer to null terminated string containing an identity token.
//
// tokenLen -
// Length of the token contained in the token buffer.
//
// ppIdenTokenIf -
// Pointer to variable that will receive pointer to identity
// token interface.
//
// Returns:
// Casa Status
//
// Description:
// Get identity token interface instance for the specified token.
//
// L2
//=======================================================================--
{
CasaStatus retStatus;
char *pDecodedTokenBuf;
int decodedTokenBufLen;
DbgTrace(2, "-GetIdentityTokenIf- Start\n", 0);
// Validate input parameters
if (pIfInstance == NULL
|| pTokenBuf == NULL
|| tokenLen == 0
|| ppIdenTokenIf == NULL)
{
DbgTrace(0, "-GetIdentityTokenIf- Invalid input parameter\n", 0);
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_INVALID_PARAMETER);
goto exit;
}
// First decode the token string
retStatus = DecodeData(pTokenBuf,
tokenLen,
(void**) &pDecodedTokenBuf,
&decodedTokenBufLen);
if (CASA_SUCCESS(retStatus))
{
// Get the identity token interface
retStatus = GetIdenTokenInterface(pDecodedTokenBuf,
decodedTokenBufLen,
ppIdenTokenIf);
// Free the decoded token buffer
free(pDecodedTokenBuf);
}
else
{
DbgTrace(0, "-GetIdentityTokenIf- Token decode failure\n", 0);
}
exit:
DbgTrace(2, "-GetIdentityTokenIf- End, retStatus = %08X\n", retStatus);
return retStatus;
}
//++=======================================================================
CasaStatus SSCS_CALL
GET_IDEN_TOKEN_PROVIDER_INTERFACE_RTN(
IN const ConfigIf *pModuleConfigIf,
INOUT IdenTokenProviderIf **ppIdenTokenProviderIf)
//
// Arguments:
// pModuleConfigIf -
// Pointer to configuration interface instance for the module.
//
// ppIdenTokenProviderIf -
// Pointer to variable that will receive pointer to
// IdentityTokenProviderIf instance.
//
// Returns:
// Casa Status
//
// Description:
// Gets identity token provider interface instance.
//
// L2
//=======================================================================--
{
CasaStatus retStatus;
IdenTokenProviderIfInstance *pIdenTokenProviderIfInstance;
DbgTrace(1, "-GetIdenTokenProviderInterface- Start\n", 0);
// Validate input parameters
if (pModuleConfigIf == NULL
|| ppIdenTokenProviderIf == NULL)
{
DbgTrace(0, "-GetIdenTokenProviderInterface- Invalid input parameter\n", 0);
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_KRB5TOKEN,
CASA_STATUS_INVALID_PARAMETER);
goto exit;
}
// Make sure that the module has been initialized
if (g_moduleInitialized == false)
{
// The module has not been initialized, synchronize access thought this section
// to avoid having two threads performing initialization.
AcquireModuleMutex;
// Assume success
retStatus = CASA_STATUS_SUCCESS;
// Check again in case another thread pre-empted us.
if (g_moduleInitialized == false)
{
// Initialize the IdenTokenIf complex
retStatus = IdenTokenIfInit();
if (CASA_SUCCESS(retStatus))
{
// Allocate mutex
if ((g_idenTokenProviderIfMutex = PlatAllocMutex()) != NULL)
{
// Success
g_moduleInitialized = true;
}
else
{
IdenTokenIfUninit();
retStatus = CasaStatusBuild(CASA_SEVERITY_INFORMATIONAL,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_INSUFFICIENT_RESOURCES);
}
}
}
// Stop synchronization
ReleaseModuleMutex;
// Exit if we failed
if (g_moduleInitialized == false)
goto exit;
}
// Allocate space for the interface instance
pIdenTokenProviderIfInstance = malloc(sizeof(*pIdenTokenProviderIfInstance));
if (pIdenTokenProviderIfInstance)
{
// Initialize the interface instance data
pIdenTokenProviderIfInstance->refCount = 1;
pIdenTokenProviderIfInstance->idenTokenProviderIf.addReference = AddReference;
pIdenTokenProviderIfInstance->idenTokenProviderIf.releaseReference = ReleaseReference;
pIdenTokenProviderIfInstance->idenTokenProviderIf.getIdentityTokenIf = GetIdentityTokenIf;
// Keep track of this object
PlatAcquireMutex(g_idenTokenProviderIfMutex);
g_numIdenTokenProviderIfObjs ++;
PlatReleaseMutex(g_idenTokenProviderIfMutex);
// Return the interface to the caller
*ppIdenTokenProviderIf = &pIdenTokenProviderIfInstance->idenTokenProviderIf;
// Success
retStatus = CASA_STATUS_SUCCESS;
}
else
{
DbgTrace(0, "-GetIdenTokenProviderInterface- Buffer allocation failure\n", 0);
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_KRB5TOKEN,
CASA_STATUS_INSUFFICIENT_RESOURCES);
}
exit:
DbgTrace(1, "-GetIdenTokenProviderInterface- End, retStatus = %08X\n", retStatus);
return retStatus;
}
//++=======================================================================
//++=======================================================================
//++=======================================================================

View File

@ -0,0 +1,122 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
#ifndef _INTERNAL_H_
#define _INTERNAL_H_
//===[ Include files ]=====================================================
#include "platform.h"
#include <expat.h>
#include <micasa_types.h>
#include <casa_status.h>
#include <casa_s_authtoken.h>
#include "config_if.h"
#include "iden_token_provider_if.h"
#include "list_entry.h"
//===[ Type definitions ]==================================================
//===[ Inlines functions ]===============================================
//===[ Function prototypes ]===============================================
//===[ Global variables ]==================================================
//===[ Global externals ]==================================================
extern int DebugLevel;
//===[ External prototypes ]===============================================
//
// Defined in identoken.c
//
extern
CasaStatus
GetIdenTokenInterface(
IN const char *pTokenBuf,
IN const int tokenLen,
INOUT IdenTokenIf **ppIdenTokenIf);
extern
CasaStatus
IdenTokenIfInit(void);
extern
void
IdenTokenIfUninit(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);
extern
int
dtoul(
IN char *cp,
IN int len);
//
// Functions exported by platform.c
//
extern
HANDLE
PlatAllocMutex(void);
extern
void
PlatDestroyMutex(HANDLE hMutex);
extern
void
PlatAcquireMutex(HANDLE hMutex);
extern
void
PlatReleaseMutex(HANDLE hMutex);
//=========================================================================
#endif // _INTERNAL_H_

View File

@ -0,0 +1,15 @@
#######################################################
# #
# CASA Authentication Token System configuration file #
# for module: #
# #
# CasaIdentityToken #
# #
# Note: This module is the provider of Casa Identity #
# tokens. #
# #
#######################################################
LibraryName /opt/novell/CASA/lib/casa_iden_token.so

View File

@ -0,0 +1,114 @@
#######################################################################
#
# Copyright (C) 2006 Novell, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# Author: Juan Carlos Luciani <jluciani@novell.com>
#
#######################################################################
if DEBUG
TARGET_CFG = Debug
CFLAGS += -v -w
else
TARGET_CFG = Release
endif
SUBDIRS =
DIST_SUBDIRS =
ROOT = ../../../../..
CASAINCLUDE = ../../../../../../CASA/include
LIBDIR = $(ROOT)/$(LIB)
# handle Mono secondary dependencies
export MONO_PATH := $(MONO_PATH)
PLATFORMINDEPENDENTSOURCEDIR = ..
PLATFORMDEPENDENTSOURCEDIR = .
MODULE_NAME = casa_iden_token
MODULE_EXT = so
CFILES = ../identokenprovider.c \
../identoken.c \
../util.c \
platform.c
CSFILES_CSC :=
INCLUDES = -I. -I.. -I../../.. -I$(CASAINCLUDE) -I../../../../../include
RESOURCES =
DEFINES = -Wno-format-extra-args -fno-strict-aliasing
CFLAGS += $(INCLUDES) $(DEFINES)
LIBS = -lpthread -ldl -lexpat
LDFLAGS = -Bsymbolic -shared -Wl,-soname=$(MODULE_NAME).$(MODULE_EXT)
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

View File

@ -0,0 +1,178 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
//===[ Include files ]=====================================================
#include "internal.h"
//===[ Type definitions ]==================================================
//
// Platform Mutex structure
//
typedef struct _PlatformMutex
{
pthread_mutex_t mutex;
} PlatformMutex, *PPlatformMutex;
//===[ Function prototypes ]===============================================
//===[ Global variables ]==================================================
//
// Module synchronization mutex
//
pthread_mutex_t g_hModuleMutex = PTHREAD_MUTEX_INITIALIZER;
//++=======================================================================
HANDLE
PlatAllocMutex(void)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// Environment:
//
// L2
//=======================================================================--
{
PlatformMutex *pPlatMutex;
pthread_mutexattr_t mutexAttr = {PTHREAD_MUTEX_RECURSIVE};
DbgTrace(2, "-PlatAllocMutex- Start\n", 0);
// Allocate space for our mutex structure
pPlatMutex = malloc(sizeof(*pPlatMutex));
if (pPlatMutex)
{
// Finish initializing the mutex
pthread_mutex_init(&pPlatMutex->mutex, &mutexAttr);
}
else
{
DbgTrace(0, "-PlatAllocMutex- Memory allocation failure\n", 0);
}
DbgTrace(2, "-PlatAllocMutex- End, retHandle = %08X\n", (unsigned int) pPlatMutex);
return (HANDLE) pPlatMutex;
}
//++=======================================================================
void
PlatDestroyMutex(HANDLE hMutex)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// Environment:
//
// L2
//=======================================================================--
{
PlatformMutex *pPlatMutex = (PlatformMutex*) hMutex;
DbgTrace(2, "-PlatDestroyMutex- Start\n", 0);
// Free the resources associated with the mutex
pthread_mutex_destroy(&pPlatMutex->mutex);
free(pPlatMutex);
DbgTrace(2, "-PlatDestroyMutex- End\n", 0);
}
//++=======================================================================
void
PlatAcquireMutex(HANDLE hMutex)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// Environment:
//
// L2
//=======================================================================--
{
PlatformMutex *pPlatMutex = (PlatformMutex*) hMutex;
DbgTrace(2, "-PlatAcquireMutex- Start\n", 0);
// Acquire the mutex
pthread_mutex_lock(&pPlatMutex->mutex);
DbgTrace(2, "-PlatAcquireMutex- End\n", 0);
}
//++=======================================================================
void
PlatReleaseMutex(HANDLE hMutex)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// Environment:
//
// L2
//=======================================================================--
{
PlatformMutex *pPlatMutex = (PlatformMutex*) hMutex;
DbgTrace(2, "-PlatReleaseMutex- Start\n", 0);
// Release the mutex
pthread_mutex_unlock(&pPlatMutex->mutex);
DbgTrace(2, "-PlatRelease- End\n", 0);
}
//++=======================================================================
//++=======================================================================
//++=======================================================================

View File

@ -0,0 +1,93 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
#define _GNU_SOURCE
//===[ Include files ]=====================================================
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <syslog.h>
#include <pthread.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <dlfcn.h>
//===[ 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_IdenToken %s", printBuff); \
} \
}
/*#define DbgTrace(LEVEL, X, Y) { \
if (LEVEL == 0 || DebugLevel >= LEVEL) \
{ \
openlog("CASA_IdenToken", 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
//
// Module synchronization
//
extern pthread_mutex_t g_hModuleMutex;
#define AcquireModuleMutex pthread_mutex_lock(&g_hModuleMutex)
#define ReleaseModuleMutex pthread_mutex_unlock(&g_hModuleMutex)
//===[ Inlines functions ]===============================================
//===[ Function prototypes ]===============================================
//===[ Global externals ]==================================================
//===[ External prototypes ]===============================================
//=========================================================================

View File

@ -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 <jluciani@novell.com>
*
***********************************************************************/
//===[ 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 char *cp,
IN int len)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// L0
//=======================================================================--
{
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;
}
//++=======================================================================
//++=======================================================================
//++=======================================================================

View File

@ -0,0 +1,356 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
#ifndef _IDEN_TOKEN_PROVIDER_IF_H_
#define _IDEN_TOKEN_PROVIDER_IF_H_
//===[ Include files ]=====================================================
#include "config_if.h"
//===[ Type definitions ]==================================================
//===[ Function prototypes ]===============================================
//===[ Global variables ]==================================================
/**************************************************************************
***************************************************************************
** **
** Identity Token Interface Definitions **
** **
***************************************************************************
**************************************************************************/
//++=======================================================================
typedef
int
(SSCS_CALL *PFNIdenTokenIf_AddReference)(
IN const void *pIfInstance);
//
// Arguments:
// pIfInstance -
// Pointer to interface object.
//
// Returns:
// Interface reference count.
//
// Description:
// Increases interface reference count.
//=======================================================================--
//++=======================================================================
typedef
void
(SSCS_CALL *PFNIdenTokenIf_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 *PFNIdenTokenIf_GetIdentityId)(
IN const void *pIfInstance,
INOUT char *pIdentIdBuf,
INOUT int *pIdentIdLen);
//
// Arguments:
// pIfInstance -
// Pointer to interface object.
//
// pIdentIdBuf -
// Pointer to buffer that will receive the identity id. The returned
// id will be in the form of a NULL terminated string.
//
// pIdentIdBufLen -
// Pointer to variable with the length of the buffer pointed by
// pIdentIdBuf. On exit it contains the length of the returned id
// (including the NULL terminator).
//
//
// Returns:
// Casa Status
//
// Description:
// Get the identity id associated with the identity token.
//=======================================================================--
//++=======================================================================
typedef
CasaStatus
(SSCS_CALL *PFNIdenTokenIf_GetSourceName)(
IN const void *pIfInstance,
INOUT char *pSourceNameBuf,
INOUT int *pSourceNameLen);
//
// Arguments:
// pIfInstance -
// Pointer to interface object.
//
// pSourceNameBuf -
// Pointer to buffer that will receive the name associated with the
// identity information source. The returned name will be in the form
// of a NULL terminated string.
//
// pSourceNameBufLen -
// Pointer to variable with the length of the buffer pointed by
// pSourceNameBuf. On exit it contains the length of the returned
// name (including the NULL terminator).
//
//
// Returns:
// Casa Status
//
// Description:
// Get the name of the identity source associated with the identity token.
//=======================================================================--
//++=======================================================================
typedef
CasaStatus
(SSCS_CALL *PFNIdenTokenIf_GetSourceUrl)(
IN const void *pIfInstance,
INOUT char *pSourceUrlBuf,
INOUT int *pSourceUrlLen);
//
// Arguments:
// pIfInstance -
// Pointer to interface object.
//
// pSourceUrlBuf -
// Pointer to buffer that will receive the URL associated with the
// identity information source. The returned URL will be in the form
// of a NULL terminated string.
//
// pSourceUrlBufLen -
// Pointer to variable with the length of the buffer pointed by
// pSourceUrlBuf. On exit it contains the length of the returned
// URL (including the NULL terminator).
//
//
// Returns:
// Casa Status
//
// Description:
// Get the URL to the identity source associated with the identity token.
//=======================================================================--
//++=======================================================================
typedef
CasaStatus
(SSCS_CALL *PFNIdenTokenIf_AttributeEnumerate)(
IN const void *pIfInstance,
INOUT int *pEnumHandle,
INOUT char *pAttribNameBuf,
INOUT int *pAttribNameLen,
INOUT char *pAttribValueBuf,
INOUT int *pAttribValueLen);
//
// Arguments:
// pIfInstance -
// Pointer to interface object.
//
// pEnumHandle -
// Pointer to enumeration handle. Must be set to 0 to start an
// enumeration. Note the enumeration handle advances if the
// function returns success.
//
// pAttribNameBuf -
// Pointer to buffer that will receive the identity attribute name. The
// returned name will be in the form of a NULL terminated string.
//
// pAttribNameLen -
// Pointer to variable with the length of the buffer pointed by
// pAttribNameBuf. On exit it contains the length of the returned
// name (including the NULL terminator).
//
// pAttribValueBuf -
// Pointer to buffer that will receive the identity attribute value. The
// returned value will be in the form of a NULL terminated string.
//
// pAttribValueLen -
// Pointer to variable with the length of the buffer pointed by
// pAttribValueBuf. On exit it contains the length of the returned
// value (including the NULL terminator).
//
//
// Returns:
// Casa Status
//
// Description:
// Enumerates through the attributes associated with the identity token.
//=======================================================================--
//
// Identity Token Interface Object
//
typedef struct _IdenTokenIf
{
PFNIdenTokenIf_AddReference addReference;
PFNIdenTokenIf_ReleaseReference releaseReference;
PFNIdenTokenIf_GetIdentityId getIdentityId;
PFNIdenTokenIf_GetSourceName getSourceName;
PFNIdenTokenIf_GetSourceUrl getSourceUrl;
PFNIdenTokenIf_AttributeEnumerate attributeEnumerate;
} IdenTokenIf, *PIdenTokenIf;
/**************************************************************************
***************************************************************************
** **
** Identity Token Provider Interface Definitions **
** **
***************************************************************************
**************************************************************************/
//++=======================================================================
typedef
int
(SSCS_CALL *PFNIdenTokenProviderIf_AddReference)(
IN const void *pIfInstance);
//
// Arguments:
// pIfInstance -
// Pointer to interface object.
//
// Returns:
// Interface reference count.
//
// Description:
// Increases interface reference count.
//=======================================================================--
//++=======================================================================
typedef
void
(SSCS_CALL *PFNIdenTokenProviderIf_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 *PFNIdenTokenProviderIf_GetIdentityTokenIf)(
IN const void *pIfInstance,
IN const char *pTokenBuf,
IN const int tokenLen,
INOUT IdenTokenIf **ppIdenTokenIf);
//
// Arguments:
// pIfInstance -
// Pointer to interface object.
//
// pTokenBuf -
// Pointer to null terminated string containing an identity token.
//
// tokenLen -
// Length of the token contained in the token buffer.
//
// ppIdenTokenIf -
// Pointer to variable that will receive pointer to identity
// token interface.
//
// Returns:
// Casa Status
//
// Description:
// Get identity token interface instance for the specified token.
//=======================================================================--
//
// Identity Token Provider Interface Object
//
typedef struct _IdenTokenProviderIf
{
PFNIdenTokenProviderIf_AddReference addReference;
PFNIdenTokenProviderIf_ReleaseReference releaseReference;
PFNIdenTokenProviderIf_GetIdentityTokenIf getIdentityTokenIf;
} IdenTokenProviderIf, *PIdenTokenProviderIf;
//++=======================================================================
typedef
CasaStatus
(SSCS_CALL *PFN_GetIdenTokenProviderIfRtn)(
IN const ConfigIf *pModuleConfigIf,
INOUT IdenTokenProviderIf **ppIdenTokenProviderIf);
//
// Arguments:
// pModuleConfigIf -
// Pointer to configuration interface instance for the module.
//
// ppIdenTokenProviderIf -
// Pointer to variable that will receive pointer to
// IdentityTokenProviderIf instance.
//
// Returns:
// Casa Status
//
// Description:
// Gets identity token provider interface instance.
//=======================================================================--
#define GET_IDEN_TOKEN_PROVIDER_INTERFACE_RTN_SYMBOL "GetIdenTokenProviderInterface"
#define GET_IDEN_TOKEN_PROVIDER_INTERFACE_RTN GetIdenTokenProviderInterface
#endif // #ifndef _IDEN_TOKEN_PROVIDER_IF_H_

View File

@ -0,0 +1,320 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
//===[ Include files ]=====================================================
#include "internal.h"
//===[ Type definitions ]==================================================
//
// Identity Token Module definition
//
typedef struct _IdenTokenProviderModule
{
LIST_ENTRY listEntry;
char *pTypeName;
int typeNameLen;
LIB_HANDLE libHandle;
IdenTokenProviderIf *pIdenTokenProviderIf;
} IdenTokenProviderModule, *PIdenTokenProviderModule;
//===[ Function prototypes ]===============================================
//===[ Global variables ]==================================================
//
// IdenTokenProviderModule list and syncronization mutex
//
static
LIST_ENTRY g_IdenTokenProviderModuleListHead = {&g_IdenTokenProviderModuleListHead, &g_IdenTokenProviderModuleListHead};
static
HANDLE g_idenTokenMutex = NULL;
//++=======================================================================
CasaStatus
GetIdenTokenProviderInterface(
IN const char *pIdenTokenTypeName,
INOUT IdenTokenProviderIf **ppIdenTokenProviderIf)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// Environment:
//
// L2
//=======================================================================--
{
CasaStatus retStatus;
ConfigIf *pModuleConfigIf;
DbgTrace(2, "-GetIdenTokenProviderInterface- Start\n", 0);
// Get the configuration for the module
retStatus = GetConfigInterface("/etc/opt/novell/CASA/authtoken.d/modules.d",
pIdenTokenTypeName,
&pModuleConfigIf);
if (CASA_SUCCESS(retStatus)
&& CasaStatusCode(retStatus) != CASA_STATUS_OBJECT_NOT_FOUND)
{
LIST_ENTRY *pListEntry;
IdenTokenProviderModule *pIdenTokenProviderModule = NULL;
int32_t idenTokenTypeNameLen = strlen(pIdenTokenTypeName);
// Gain exclusive access to our mutex
PlatAcquireMutex(g_idenTokenMutex);
// Look if we already have the module in our list
pListEntry = g_IdenTokenProviderModuleListHead.Flink;
while (pListEntry != &g_IdenTokenProviderModuleListHead)
{
// Get pointer to the current entry
pIdenTokenProviderModule = CONTAINING_RECORD(pListEntry, IdenTokenProviderModule, listEntry);
// Check if this is the module that we need
if (pIdenTokenProviderModule->typeNameLen == idenTokenTypeNameLen
&& memcmp(pIdenTokenTypeName, pIdenTokenProviderModule->pTypeName, idenTokenTypeNameLen) == 0)
{
// This is the module that we need, stop looking.
break;
}
else
{
// This is not the module that we are looking for
pIdenTokenProviderModule = NULL;
}
// Advance to the next entry
pListEntry = pListEntry->Flink;
}
// Proceed based on whether or not a module was found
if (pIdenTokenProviderModule)
{
// Module found in our list, provide the caller with its IdenTokenProviderIf
// instance after we have incremented its reference count.
pIdenTokenProviderModule->pIdenTokenProviderIf->addReference(pIdenTokenProviderModule->pIdenTokenProviderIf);
*ppIdenTokenProviderIf = pIdenTokenProviderModule->pIdenTokenProviderIf;
// Success
retStatus = CASA_STATUS_SUCCESS;
}
else
{
// Needed module not found in our list, create an entry.
pIdenTokenProviderModule = malloc(sizeof(*pIdenTokenProviderModule));
if (pIdenTokenProviderModule)
{
// Allocate buffer to contain the authentication type name within the module entry
pIdenTokenProviderModule->pTypeName = malloc(idenTokenTypeNameLen + 1);
if (pIdenTokenProviderModule->pTypeName)
{
char *pLibraryName;
// Initialize the library handle field
pIdenTokenProviderModule->libHandle = NULL;
// Save the auth type name within the entry
strcpy(pIdenTokenProviderModule->pTypeName, pIdenTokenTypeName);
pIdenTokenProviderModule->typeNameLen = idenTokenTypeNameLen;
// Obtain the name of the library that we must load
pLibraryName = pModuleConfigIf->getEntryValue(pModuleConfigIf, "LibraryName");
if (pLibraryName)
{
// Load the library
pIdenTokenProviderModule->libHandle = OpenLibrary(pLibraryName);
if (pIdenTokenProviderModule->libHandle)
{
PFN_GetIdenTokenProviderIfRtn pGetIdenTokenProviderIfRtn;
// Library has been loaded, now get a pointer to its GetIdenTokenProviderProviderInterface routine
pGetIdenTokenProviderIfRtn = (PFN_GetIdenTokenProviderIfRtn) GetFunctionPtr(pIdenTokenProviderModule->libHandle,
GET_IDEN_TOKEN_PROVIDER_INTERFACE_RTN_SYMBOL);
if (pGetIdenTokenProviderIfRtn)
{
// Now, obtain the modules IdenTokenProviderIf.
retStatus = (pGetIdenTokenProviderIfRtn)(pModuleConfigIf, &pIdenTokenProviderModule->pIdenTokenProviderIf);
}
else
{
DbgTrace(0, "-GetIdenTokenProviderInterface- GetFunctionPtr error\n", 0);
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_LIBRARY_LOAD_FAILURE);
}
}
else
{
DbgTrace(0, "-GetIdenTokenProviderInterface- OpenLibrary error\n", 0);
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_LIBRARY_LOAD_FAILURE);
}
// Free the buffer holding the library name
free(pLibraryName);
}
else
{
DbgTrace(0, "-GetIdenTokenProviderInterface- 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 IdenTokenProviderIf instance for the
// module.
if (CASA_SUCCESS(retStatus))
{
// Insert the entry in the list, provide the caller with its IdenTokenProviderIf
// instance after we have incremented its reference count.
InsertTailList(&g_IdenTokenProviderModuleListHead, &pIdenTokenProviderModule->listEntry);
pIdenTokenProviderModule->pIdenTokenProviderIf->addReference(pIdenTokenProviderModule->pIdenTokenProviderIf);
*ppIdenTokenProviderIf = pIdenTokenProviderModule->pIdenTokenProviderIf;
}
else
{
// Failed, free resources.
free(pIdenTokenProviderModule->pTypeName);
if (pIdenTokenProviderModule->libHandle)
CloseLibrary(pIdenTokenProviderModule->libHandle);
free(pIdenTokenProviderModule);
}
}
else
{
DbgTrace(0, "-GetIdenTokenProviderInterface- Unable to allocate buffer\n", 0);
// Free buffer allocated for entry
free(pIdenTokenProviderModule);
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_INSUFFICIENT_RESOURCES);
}
}
else
{
DbgTrace(0, "-GetIdenTokenProviderInterface- Unable to allocate buffer\n", 0);
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_INSUFFICIENT_RESOURCES);
}
}
// Release exclusive access to our mutex
PlatReleaseMutex(g_idenTokenMutex);
// Release config interface instance
pModuleConfigIf->releaseReference(pModuleConfigIf);
}
else
{
DbgTrace(0, "-GetIdenTokenProviderInterface- Unable to obtain config interface\n", 0);
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_CONFIGURATION_ERROR);
}
DbgTrace(2, "-GetIdenTokenProviderInterface- End, retStatus = %08X\n", retStatus);
return retStatus;
}
//++=======================================================================
CasaStatus
IdenTokenInit(void)
//
// Arguments:
//
// Returns:
// Casa Status
//
// Description:
// Initializes the identity token complex.
//
// L2
//=======================================================================--
{
CasaStatus retStatus;
DbgTrace(1, "-IdenTokenInit- Start\n", 0);
// Allocate mutex
if ((g_idenTokenMutex = PlatAllocMutex()) != NULL)
retStatus = CASA_STATUS_SUCCESS;
else
retStatus = CasaStatusBuild(CASA_SEVERITY_INFORMATIONAL,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_INSUFFICIENT_RESOURCES);
DbgTrace(1, "-IdenTokenInit- End, retStatus = %08X\n", retStatus);
return retStatus;
}
//++=======================================================================
void
IdenTokenUninit(void)
//
// Arguments:
//
// Returns:
// Casa Status
//
// Description:
// Uninitializes the indentity token complex.
//
// L2
//=======================================================================--
{
DbgTrace(1, "-IdenTokenUninit- Start\n", 0);
// Free mutex if necessary
if (g_idenTokenMutex)
{
PlatDestroyMutex(g_idenTokenMutex);
g_idenTokenMutex = NULL;
}
DbgTrace(1, "-IdenTokenUninit- End\n", 0);
}
//++=======================================================================
//++=======================================================================
//++=======================================================================

View File

@ -0,0 +1,222 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
#ifndef _INTERNAL_H_
#define _INTERNAL_H_
//===[ Include files ]=====================================================
#include "platform.h"
#include <expat.h>
#include <micasa_types.h>
#include <casa_status.h>
#include <casa_s_authtoken.h>
#include "proto.h"
#include "list_entry.h"
#include "config_if.h"
#include "iden_token_provider_if.h"
//===[ Type definitions ]==================================================
//
// Authentication Token structure
//
typedef struct _AuthToken
{
int tokenLifetime;
char *pSignature;
int signatureLen;
char *pIdenTokenType;
int idenTokenTypeLen;
char *pIdenToken;
int idenTokenLen;
} AuthToken, *PAuthToken;
//===[ Inlines functions ]===============================================
//===[ Function prototypes ]===============================================
//===[ Global variables ]==================================================
//===[ Global externals ]==================================================
extern int DebugLevel;
//===[ External prototypes ]===============================================
//
// Functions exported by config.c
//
extern
CasaStatus
GetConfigInterface(
IN const char *pConfigFolder,
IN const char *pConfigName,
INOUT ConfigIf **ppConfigIf);
extern
CasaStatus
ConfigIfInit(void);
extern
void
ConfigIfUninit(void);
//
// Functions exported by identoken.c
//
extern
CasaStatus
GetIdenTokenProviderInterface(
IN const char *pIdenTokenTypeName,
INOUT IdenTokenProviderIf **ppIdenTokenProviderIf);
extern
CasaStatus
IdenTokenInit(void);
extern
void
IdenTokenUninit(void);
//
// Functions exported by platform.c
//
extern
HANDLE
PlatAllocMutex(void);
extern
void
PlatDestroyMutex(HANDLE hMutex);
extern
void
PlatAcquireMutex(HANDLE hMutex);
extern
void
PlatReleaseMutex(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);
//
// Functions exported by principal.c
//
extern
CasaStatus
GetPrincipalInterface(
IN IdenTokenIf *pIdenTokenIf,
INOUT PrincipalIf **ppPrincipalIf);
extern
CasaStatus
PrincipalIfInit(void);
extern
void
PrincipalIfUninit(void);
//
// Functions exported by validate.c
//
extern
CasaStatus SSCS_CALL
ValidateAuthToken(
IN const char *pServiceName,
IN const char *pTokenBuf,
IN const int tokenBufLen,
INOUT PrincipalIf **ppPrincipalIf);
//
// Functions exported by authtoken.c
//
extern
CasaStatus
CreateAuthToken(
IN char *pTokenBuf,
IN int tokenBufLen,
INOUT AuthToken **ppAuthToken);
extern
void
RelAuthToken(
IN AuthToken *pAuthToken);
extern
CasaStatus
CheckAuthToken(
IN AuthToken *pAuthToken,
IN const char *pServiceName);
//
// 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);
extern
int
dtoul(
IN char *cp,
IN int len);
//=========================================================================
#endif // _INTERNAL_H_

View File

@ -0,0 +1,116 @@
#######################################################################
#
# Copyright (C) 2006 Novell, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# Author: Juan Carlos Luciani <jluciani@novell.com>
#
#######################################################################
if DEBUG
TARGET_CFG = Debug
CFLAGS += -v -w
else
TARGET_CFG = Release
endif
SUBDIRS =
DIST_SUBDIRS =
ROOT = ../../..
CASAINCLUDE = ../../../../CASA/include
LIBDIR = $(ROOT)/$(LIB)
# handle Mono secondary dependencies
export MONO_PATH := $(MONO_PATH)
PLATFORMINDEPENDENTSOURCEDIR = ..
PLATFORMDEPENDENTSOURCEDIR = .
MODULE_NAME = libcasa_s_authtoken
MODULE_EXT = so
CFILES = ../config.c \
../authtoken.c \
../principal.c \
../util.c \
../validate.c \
../identoken.c \
platform.c
CSFILES_CSC :=
INCLUDES = -I. -I.. -I$(CASAINCLUDE) -I../../../include
RESOURCES =
DEFINES = -Wno-format-extra-args -fno-strict-aliasing
CFLAGS += $(INCLUDES) $(DEFINES)
LIBS = -lpthread -ldl -lexpat
LDFLAGS = -Bsymbolic -shared -Wl,-soname=$(MODULE_NAME).$(MODULE_EXT)
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

View File

@ -0,0 +1,268 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
//===[ Include files ]=====================================================
#include "internal.h"
//===[ Type definitions ]==================================================
//
// Platform Mutex structure
//
typedef struct _PlatformMutex
{
pthread_mutex_t mutex;
} PlatformMutex, *PPlatformMutex;
//===[ Function prototypes ]===============================================
//===[ Global variables ]==================================================
//
// Module synchronization mutex
//
pthread_mutex_t g_hModuleMutex = PTHREAD_MUTEX_INITIALIZER;
//++=======================================================================
HANDLE
PlatAllocMutex(void)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// Environment:
//
// L2
//=======================================================================--
{
PlatformMutex *pPlatMutex;
pthread_mutexattr_t mutexAttr = {PTHREAD_MUTEX_RECURSIVE};
DbgTrace(2, "-PlatAllocMutex- Start\n", 0);
// Allocate space for our mutex structure
pPlatMutex = malloc(sizeof(*pPlatMutex));
if (pPlatMutex)
{
// Finish initializing the mutex
pthread_mutex_init(&pPlatMutex->mutex, &mutexAttr);
}
else
{
DbgTrace(0, "-PlatAllocMutex- Memory allocation failure\n", 0);
}
DbgTrace(2, "-PlatAllocMutex- End, retHandle = %08X\n", (unsigned int) pPlatMutex);
return (HANDLE) pPlatMutex;
}
//++=======================================================================
void
PlatDestroyMutex(HANDLE hMutex)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// Environment:
//
// L2
//=======================================================================--
{
PlatformMutex *pPlatMutex = (PlatformMutex*) hMutex;
DbgTrace(2, "-PlatDestroyMutex- Start\n", 0);
// Free the resources associated with the mutex
pthread_mutex_destroy(&pPlatMutex->mutex);
free(pPlatMutex);
DbgTrace(2, "-PlatDestroyMutex- End\n", 0);
}
//++=======================================================================
void
PlatAcquireMutex(HANDLE hMutex)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// Environment:
//
// L2
//=======================================================================--
{
PlatformMutex *pPlatMutex = (PlatformMutex*) hMutex;
DbgTrace(2, "-PlatAcquireMutex- Start\n", 0);
// Acquire the mutex
pthread_mutex_lock(&pPlatMutex->mutex);
DbgTrace(2, "-PlatAcquireMutex- End\n", 0);
}
//++=======================================================================
void
PlatReleaseMutex(HANDLE hMutex)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// Environment:
//
// L2
//=======================================================================--
{
PlatformMutex *pPlatMutex = (PlatformMutex*) hMutex;
DbgTrace(2, "-PlatReleaseMutex- Start\n", 0);
// Release the mutex
pthread_mutex_unlock(&pPlatMutex->mutex);
DbgTrace(2, "-PlatRelease- 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 = %d\n", dlerror());
}
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);
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 = %d\n", dlerror());
}
DbgTrace(1, "-GetFunctionPtr- End, pFuncPtr = %08X\n", pFuncPtr);
return pFuncPtr;
}
//++=======================================================================
//++=======================================================================
//++=======================================================================

View File

@ -0,0 +1,100 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
#define _GNU_SOURCE
//===[ Include files ]=====================================================
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <syslog.h>
#include <pthread.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <dlfcn.h>
//===[ 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_AuthTokenValidate %s", printBuff); \
} \
}
/*#define DbgTrace(LEVEL, X, Y) { \
if (LEVEL == 0 || DebugLevel >= LEVEL) \
{ \
openlog("CASA_AuthTokenValidate", 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
//
// Module synchronization
//
extern pthread_mutex_t g_hModuleMutex;
#define AcquireModuleMutex pthread_mutex_lock(&g_hModuleMutex)
#define ReleaseModuleMutex pthread_mutex_unlock(&g_hModuleMutex)
//
// Other definitions
//
#define LIB_HANDLE void*
//===[ Inlines functions ]===============================================
//===[ Function prototypes ]===============================================
//===[ Global externals ]==================================================
//===[ External prototypes ]===============================================
//=========================================================================

View File

@ -0,0 +1,482 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
//===[ Include files ]=====================================================
#include "internal.h"
//===[ Type definitions ]==================================================
//
// Config Interface instance data
//
typedef struct _PrincipalIfInstance
{
int refCount;
IdenTokenIf *pIdenTokenIf;
PrincipalIf principalIf;
} PrincipalIfInstance, *PPrincipalIfInstance;
//===[ Function prototypes ]===============================================
//===[ Global variables ]==================================================
// PrincipalIf variables
static
int g_numPrincipalIfObjs = 0;
// Synchronization mutex
static
HANDLE g_principalIfMutex = NULL;
//++=======================================================================
static
int SSCS_CALL
AddReference(
IN const void *pIfInstance)
//
// Arguments:
// pIfInstance -
// Pointer to interface object.
//
// Returns:
// Interface reference count.
//
// Description:
// Increases interface reference count.
//
// L2
//=======================================================================--
{
int refCount;
PrincipalIfInstance *pPrincipalIfInstance = CONTAINING_RECORD(pIfInstance, PrincipalIfInstance, principalIf);
DbgTrace(2, "-AddReference- Start\n", 0);
// Increment the reference count on the object
PlatAcquireMutex(g_principalIfMutex);
pPrincipalIfInstance->refCount ++;
refCount = pPrincipalIfInstance->refCount;
PlatReleaseMutex(g_principalIfMutex);
DbgTrace(2, "-AddReference- End, refCount = %08X\n", refCount);
return refCount;
}
//++=======================================================================
static
void SSCS_CALL
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;
PrincipalIfInstance *pPrincipalIfInstance = CONTAINING_RECORD(pIfInstance, PrincipalIfInstance, principalIf);
DbgTrace(2, "-ReleaseReference- Start\n", 0);
// Decrement the reference count on the object and determine if it needs to
// be released.
PlatAcquireMutex(g_principalIfMutex);
pPrincipalIfInstance->refCount --;
if (pPrincipalIfInstance->refCount == 0)
{
// The object needs to be released, forget about it.
freeObj = true;
g_numPrincipalIfObjs --;
}
PlatReleaseMutex(g_principalIfMutex);
// Free object if necessary
if (freeObj)
{
// Release the identity token interface associated with our instance
pPrincipalIfInstance->pIdenTokenIf->releaseReference(pPrincipalIfInstance->pIdenTokenIf);
// Free our instance data
free(pPrincipalIfInstance);
}
DbgTrace(2, "-ReleaseReference- End\n", 0);
}
//++=======================================================================
static
CasaStatus SSCS_CALL
GetIdentityId(
IN const void *pIfInstance,
INOUT char *pIdentIdBuf,
INOUT int *pIdentIdLen)
//
// Arguments:
// pIfInstance -
// Pointer to interface object.
//
// pIdentIdBuf -
// Pointer to buffer that will receive the identity id. The returned
// id will be in the form of a NULL terminated string.
//
// pIdentIdBufLen -
// Pointer to variable with the length of the buffer pointed by
// pIdentIdBuf. On exit it contains the length of the returned id
// (including the NULL terminator).
//
//
// Returns:
// Casa Status
//
// Description:
// Get the identity id associated with the identity token.
//
// L2
//=======================================================================--
{
CasaStatus retStatus;
PrincipalIfInstance *pPrincipalIfInstance = CONTAINING_RECORD(pIfInstance, PrincipalIfInstance, principalIf);
DbgTrace(2, "-GetIdentityId- Start\n", 0);
// Just call into the identity token
retStatus = pPrincipalIfInstance->pIdenTokenIf->getIdentityId(pPrincipalIfInstance->pIdenTokenIf,
pIdentIdBuf,
pIdentIdLen);
DbgTrace(2, "-GetIdentityId- End, retStatus = %08X\n", retStatus);
return retStatus;
}
//++=======================================================================
static
CasaStatus SSCS_CALL
GetSourceName(
IN const void *pIfInstance,
INOUT char *pSourceNameBuf,
INOUT int *pSourceNameLen)
//
// Arguments:
// pIfInstance -
// Pointer to interface object.
//
// pSourceNameBuf -
// Pointer to buffer that will receive the name associated with the
// identity information source. The returned name will be in the form
// of a NULL terminated string.
//
// pSourceNameBufLen -
// Pointer to variable with the length of the buffer pointed by
// pSourceNameBuf. On exit it contains the length of the returned
// name (including the NULL terminator).
//
//
// Returns:
// Casa Status
//
// Description:
// Get the name of the identity source associated with the identity token.
//
// L2
//=======================================================================--
{
CasaStatus retStatus;
PrincipalIfInstance *pPrincipalIfInstance = CONTAINING_RECORD(pIfInstance, PrincipalIfInstance, principalIf);
DbgTrace(2, "-GetSourceName- Start\n", 0);
// Just call into the identity token
retStatus = pPrincipalIfInstance->pIdenTokenIf->getSourceName(pPrincipalIfInstance->pIdenTokenIf,
pSourceNameBuf,
pSourceNameLen);
DbgTrace(2, "-GetSourceName- End, retStatus = %08X\n", retStatus);
return retStatus;
}
//++=======================================================================
static
CasaStatus SSCS_CALL
GetSourceUrl(
IN const void *pIfInstance,
INOUT char *pSourceUrlBuf,
INOUT int *pSourceUrlLen)
//
// Arguments:
// pIfInstance -
// Pointer to interface object.
//
// pSourceUrlBuf -
// Pointer to buffer that will receive the URL associated with the
// identity information source. The returned URL will be in the form
// of a NULL terminated string.
//
// pSourceUrlBufLen -
// Pointer to variable with the length of the buffer pointed by
// pSourceUrlBuf. On exit it contains the length of the returned
// URL (including the NULL terminator).
//
//
// Returns:
// Casa Status
//
// Description:
// Get the URL to the identity source associated with the identity token.
//
// L2
//=======================================================================--
{
CasaStatus retStatus;
PrincipalIfInstance *pPrincipalIfInstance = CONTAINING_RECORD(pIfInstance, PrincipalIfInstance, principalIf);
DbgTrace(2, "-GetSourceUrl- Start\n", 0);
// Just call into the identity token
retStatus = pPrincipalIfInstance->pIdenTokenIf->getSourceUrl(pPrincipalIfInstance->pIdenTokenIf,
pSourceUrlBuf,
pSourceUrlLen);
DbgTrace(2, "-GetSourceUrl- End, retStatus = %08X\n", retStatus);
return retStatus;
}
//++=======================================================================
static
CasaStatus SSCS_CALL
AttributeEnumerate(
IN const void *pIfInstance,
INOUT int *pEnumHandle,
INOUT char *pAttribNameBuf,
INOUT int *pAttribNameLen,
INOUT char *pAttribValueBuf,
INOUT int *pAttribValueLen)
//
// Arguments:
// pIfInstance -
// Pointer to interface object.
//
// pEnumHandle -
// Pointer to enumeration handle. Must be set to 0 to start an
// enumeration.
//
// pAttribNameBuf -
// Pointer to buffer that will receive the identity attribute name. The
// returned name will be in the form of a NULL terminated string.
//
// pAttribNameLen -
// Pointer to variable with the length of the buffer pointed by
// pAttribNameBuf. On exit it contains the length of the returned
// name (including the NULL terminator).
//
// pAttribValueBuf -
// Pointer to buffer that will receive the identity attribute value. The
// returned value will be in the form of a NULL terminated string.
//
// pAttribValueLen -
// Pointer to variable with the length of the buffer pointed by
// pAttribValueBuf. On exit it contains the length of the returned
// value (including the NULL terminator).
//
//
// Returns:
// Casa Status
//
// Description:
// Enumerates through the attributes associated with the identity token.
//
// L2
//=======================================================================--
{
CasaStatus retStatus;
PrincipalIfInstance *pPrincipalIfInstance = CONTAINING_RECORD(pIfInstance, PrincipalIfInstance, principalIf);
DbgTrace(2, "-AttributeEnumerate- Start\n", 0);
// Just call into the identity token
retStatus = pPrincipalIfInstance->pIdenTokenIf->attributeEnumerate(pPrincipalIfInstance->pIdenTokenIf,
pEnumHandle,
pAttribNameBuf,
pAttribNameLen,
pAttribValueBuf,
pAttribValueLen);
DbgTrace(2, "-AttributeEnumerate- End, retStatus = %08X\n", retStatus);
return retStatus;
}
//++=======================================================================
CasaStatus
GetPrincipalInterface(
IN IdenTokenIf *pIdenTokenIf,
INOUT PrincipalIf **ppPrincipalIf)
//
// Arguments:
//
// Returns:
// Casa Status
//
// Description:
// Get principal interface instanced for the identity associated
// with specified identity token.
//
// L2
//=======================================================================--
{
PrincipalIfInstance *pPrincipalIfInstance;
CasaStatus retStatus;
DbgTrace(2, "-GetPrincipalInterface- Start\n", 0);
// Create a PrincipalIfInstance object for it.
pPrincipalIfInstance = malloc(sizeof(*pPrincipalIfInstance));
if (pPrincipalIfInstance)
{
// Initialize the PrincipalIf within the instance data
pPrincipalIfInstance->principalIf.addReference = AddReference;
pPrincipalIfInstance->principalIf.releaseReference = ReleaseReference;
pPrincipalIfInstance->principalIf.getIdentityId = GetIdentityId;
pPrincipalIfInstance->principalIf.getSourceName = GetSourceName;
pPrincipalIfInstance->principalIf.getSourceUrl = GetSourceUrl;
pPrincipalIfInstance->principalIf.attributeEnumerate = AttributeEnumerate;
// Keep reference to the identity token interface instance
pPrincipalIfInstance->pIdenTokenIf = pIdenTokenIf;
pIdenTokenIf->addReference(pIdenTokenIf);
// Return the PrincipalIf associated with the instance data after
// incrementing its reference count.
pPrincipalIfInstance->refCount ++;
*ppPrincipalIf = &pPrincipalIfInstance->principalIf;
// Bump up our interface instance count
PlatAcquireMutex(g_principalIfMutex);
g_numPrincipalIfObjs ++;
PlatReleaseMutex(g_principalIfMutex);
// Success
retStatus = CASA_STATUS_SUCCESS;
}
else
{
DbgTrace(0, "-GetPrincipalInterface- Buffer allocation failure\n", 0);
retStatus = CasaStatusBuild(CASA_SEVERITY_INFORMATIONAL,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_INSUFFICIENT_RESOURCES);
}
DbgTrace(2, "-GetPrincipalInterface- End, retStatus = %08X\n", retStatus);
return retStatus;
}
//++=======================================================================
CasaStatus
PrincipalIfInit(void)
//
// Arguments:
//
// Returns:
// Casa Status
//
// Description:
// Initializes the principal interface complex.
//
// L2
//=======================================================================--
{
CasaStatus retStatus;
DbgTrace(1, "-PrincipalIfInit- Start\n", 0);
// Allocate mutex
if ((g_principalIfMutex = PlatAllocMutex()) != NULL)
retStatus = CASA_STATUS_SUCCESS;
else
retStatus = CasaStatusBuild(CASA_SEVERITY_INFORMATIONAL,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_INSUFFICIENT_RESOURCES);
DbgTrace(1, "-PrincipalIfInit- End, retStatus = %08X\n", retStatus);
return retStatus;
}
//++=======================================================================
void
PrincipalIfUninit(void)
//
// Arguments:
//
// Returns:
// Casa Status
//
// Description:
// Uninitializes the configuration interface complex.
//
// L2
//=======================================================================--
{
DbgTrace(1, "-PrincipalIfUninit- Start\n", 0);
// Free mutex if necessary
if (g_principalIfMutex)
{
PlatDestroyMutex(g_principalIfMutex);
g_principalIfMutex = NULL;
}
DbgTrace(1, "-PrincipalIfUninit- End\n", 0);
}
//++=======================================================================
//++=======================================================================
//++=======================================================================

View File

@ -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 <jluciani@novell.com>
*
***********************************************************************/
//===[ 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 char *cp,
IN 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;
}
//++=======================================================================
//++=======================================================================
//++=======================================================================

View File

@ -0,0 +1,244 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
//===[ Include files ]=====================================================
#include "internal.h"
//===[ Type definitions ]==================================================
//===[ Function prototypes ]===============================================
//===[ Global variables ]==================================================
// Debug Level
int DebugLevel = 0;
//
// Initialization variables
//
static
bool g_moduleInitialized = false;
//++=======================================================================
CasaStatus SSCS_CALL
ValidateAuthToken(
IN const char *pServiceName,
IN const char *pTokenBuf,
IN const int tokenBufLen,
INOUT PrincipalIf **ppPrincipalIf)
//
// Arguments:
// pServiceName -
// Pointer to NULL terminated string that contains the
// name of the service targeted by the token.
//
// 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.
//
// tokenBufLen -
// Length of the data contained within the buffer pointed
// at by pTokenBuf.
//
// ppPrincipalIf -
// Pointer to variable that will receive a pointer to a principal
// interface with information about the authenticated entity.
// IMPORTANT NOTE: The caller is responsible for releasing the
// interface after it is done with it to avoid a resource leak.
//
// Returns:
// Casa status.
//
// Description:
// Validates authentication token.
//
// L2
//=======================================================================--
{
CasaStatus retStatus;
char *pDecodedTokenBuf;
int decodedTokenBufLen;
PrincipalIf *pPrincipalIf;
DbgTrace(1, "-ValidateAuthToken- Start\n", 0);
// Validate input parameters
if (pServiceName == NULL
|| pTokenBuf == NULL
|| tokenBufLen == 0
|| ppPrincipalIf == NULL)
{
DbgTrace(0, "-ValidateAuthToken- Invalid input parameter\n", 0);
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_INVALID_PARAMETER);
goto exit;
}
// Make sure that the module has been initialized
if (g_moduleInitialized == false)
{
// The module has not been initialized, synchronize access thought this section
// to avoid having two threads performing initialization.
AcquireModuleMutex;
// Assume success
retStatus = CASA_STATUS_SUCCESS;
// Check again in case another thread pre-empted us.
if (g_moduleInitialized == false)
{
// Initialize the ConfigIf complex
retStatus = ConfigIfInit();
if (CASA_SUCCESS(retStatus))
{
// Initialize the PrincipalIf complex
retStatus = PrincipalIfInit();
if (CASA_SUCCESS(retStatus))
{
// Initialize the IdenToken complex
retStatus = IdenTokenInit();
if (CASA_SUCCESS(retStatus))
{
// Success
g_moduleInitialized = true;
}
else
{
PrincipalIfUninit();
ConfigIfUninit();
}
}
else
{
ConfigIfUninit();
}
}
}
// Stop synchronization
ReleaseModuleMutex;
// Exit if we failed
if (g_moduleInitialized == false)
goto exit;
}
// First decode the token string
retStatus = DecodeData(pTokenBuf,
tokenBufLen,
(void**) &pDecodedTokenBuf,
&decodedTokenBufLen);
if (CASA_SUCCESS(retStatus))
{
AuthToken *pAuthToken;
// Token was decoded successfully, now create an authentication token object with it.
retStatus = CreateAuthToken(pDecodedTokenBuf, decodedTokenBufLen, &pAuthToken);
if (CASA_SUCCESS(retStatus))
{
// Now check the validity of the token
retStatus = CheckAuthToken(pAuthToken, pServiceName);
if (CASA_SUCCESS(retStatus))
{
IdenTokenProviderIf *pIdenTokenProviderIf;
// The token was validated, now
// Obtain Identity Token Provider interface
retStatus = GetIdenTokenProviderInterface(pAuthToken->pIdenTokenType,
&pIdenTokenProviderIf);
if (CASA_SUCCESS(retStatus))
{
IdenTokenIf *pIdenTokenIf;
// Use the Identity Token Provider to get an Identity Token Interface instance
retStatus = pIdenTokenProviderIf->getIdentityTokenIf(pIdenTokenProviderIf,
pAuthToken->pIdenToken,
pAuthToken->idenTokenLen,
&pIdenTokenIf);
if (CASA_SUCCESS(retStatus))
{
// Now create a principal interface instance with the identity information present in
// the identity token.
retStatus = GetPrincipalInterface(pIdenTokenIf, &pPrincipalIf);
if (CASA_SUCCESS(retStatus))
{
// Success, return the principal interface to the caller.
*ppPrincipalIf = pPrincipalIf;
}
else
{
DbgTrace(0, "-ValidateAuthToken- Failed to instantiate principal interface\n", 0);
}
// Release identity token interface
pIdenTokenIf->releaseReference(pIdenTokenIf);
}
else
{
DbgTrace(0, "-ValidateAuthToken- Failed to instantiate identity token\n", 0);
}
// Release identity token provider interface
pIdenTokenProviderIf->releaseReference(pIdenTokenProviderIf);
}
else
{
DbgTrace(0, "-ValidateAuthToken- Failed to obtain identity token provider interface\n", 0);
}
}
// Free the AuthToken object
RelAuthToken(pAuthToken);
}
else
{
DbgTrace(0, "-ValidateAuthToken- Failed to create authentication token object\n", 0);
}
// Free the decoded token buffer
free(pDecodedTokenBuf);
}
else
{
DbgTrace(0, "-ValidateAuthToken- Token decode failure\n", 0);
}
exit:
DbgTrace(1, "-ValidateAuthToken- End, retStatus = %08X\n", retStatus);
return retStatus;
}
//++=======================================================================
//++=======================================================================
//++=======================================================================

View File

@ -0,0 +1,37 @@
#######################################################################
#
# Copyright (C) 2006 Novell, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# Author: Juan Carlos Luciani <jluciani@novell.com>
#
#######################################################################
SUBDIRS = AuthTokenValidate ApacheSupport PamSupport
DIST_SUBDIRS = AuthTokenValidate ApacheSupport PamSupport
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

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