major source structure and module name changes
This commit is contained in:
37
CASA-auth-token/Makefile.am
Normal file
37
CASA-auth-token/Makefile.am
Normal file
@@ -0,0 +1,37 @@
|
||||
#######################################################################
|
||||
#
|
||||
# Copyright (C) 2006 Novell, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public
|
||||
# License along with this program; if not, write to the Free
|
||||
# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
# Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
SUBDIRS = server
|
||||
|
||||
DIST_SUBDIRS = include server
|
||||
|
||||
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
|
||||
|
||||
90
CASA-auth-token/README
Normal file
90
CASA-auth-token/README
Normal file
@@ -0,0 +1,90 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* README for auth_token
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
INTRODUCTION
|
||||
|
||||
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 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.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
17
CASA-auth-token/TODO
Normal file
17
CASA-auth-token/TODO
Normal 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.
|
||||
|
||||
60
CASA-auth-token/auth.sln
Normal file
60
CASA-auth-token/auth.sln
Normal 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
|
||||
67
CASA-auth-token/client/README
Normal file
67
CASA-auth-token/client/README
Normal 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.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
18
CASA-auth-token/client/TODO
Normal file
18
CASA-auth-token/client/TODO
Normal 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.
|
||||
|
||||
339
CASA-auth-token/client/authmech.c
Normal file
339
CASA-auth-token/client/authmech.c
Normal file
@@ -0,0 +1,339 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail,
|
||||
* you may find current contact information at www.novell.com.
|
||||
*
|
||||
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
|
||||
//===[ 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;
|
||||
}
|
||||
|
||||
|
||||
//++=======================================================================
|
||||
//++=======================================================================
|
||||
//++=======================================================================
|
||||
|
||||
803
CASA-auth-token/client/authmsg.c
Normal file
803
CASA-auth-token/client/authmsg.c
Normal 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);
|
||||
}
|
||||
|
||||
|
||||
//++=======================================================================
|
||||
//++=======================================================================
|
||||
//++=======================================================================
|
||||
|
||||
801
CASA-auth-token/client/authpolicy.c
Normal file
801
CASA-auth-token/client/authpolicy.c
Normal 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);
|
||||
}
|
||||
|
||||
|
||||
//++=======================================================================
|
||||
//++=======================================================================
|
||||
//++=======================================================================
|
||||
|
||||
@@ -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"
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
209
CASA-auth-token/client/client.vcproj
Normal file
209
CASA-auth-token/client/client.vcproj
Normal 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 "XML_STATIC""
|
||||
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=""..\..\..\Expat-2.0.0\StaticLibs""
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/client.pdb"
|
||||
SubSystem="0"
|
||||
ImportLibrary="$(SolutionDir)client\windows/$(TargetName).lib"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
CommandLine="mkdir \"Program Files"\novell\
|
||||
mkdir \"Program Files"\novell\casa
|
||||
mkdir \"Program Files"\novell\casa\lib\
|
||||
copy $(OutDir)\authtoken.dll \"Program Files"\novell\casa\lib\authtoken.dll
|
||||
copy $(SolutionDir)client\windows\authtoken.lib \"Program Files"\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 "XML_STATIC""
|
||||
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=""..\..\..\Expat-2.0.0\StaticLibs""
|
||||
GenerateDebugInformation="TRUE"
|
||||
SubSystem="0"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
ImportLibrary="$(SolutionDir)client\windows\$(TargetName).lib"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
CommandLine="mkdir \"Program Files"\novell\
|
||||
mkdir \"Program Files"\novell\casa
|
||||
mkdir \"Program Files"\novell\casa\lib\
|
||||
copy $(OutDir)\authtoken.dll \"Program Files"\novell\casa\lib\authtoken.dll
|
||||
copy $(SolutionDir)client\windows\authtoken.lib \"Program Files"\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>
|
||||
685
CASA-auth-token/client/config.c
Normal file
685
CASA-auth-token/client/config.c
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
//++=======================================================================
|
||||
//++=======================================================================
|
||||
//++=======================================================================
|
||||
|
||||
120
CASA-auth-token/client/config_if.h
Normal file
120
CASA-auth-token/client/config_if.h
Normal 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_
|
||||
|
||||
663
CASA-auth-token/client/engine.c
Normal file
663
CASA-auth-token/client/engine.c
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
//++=======================================================================
|
||||
//++=======================================================================
|
||||
//++=======================================================================
|
||||
|
||||
745
CASA-auth-token/client/getpolicymsg.c
Normal file
745
CASA-auth-token/client/getpolicymsg.c
Normal 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);
|
||||
}
|
||||
|
||||
|
||||
//++=======================================================================
|
||||
//++=======================================================================
|
||||
//++=======================================================================
|
||||
|
||||
793
CASA-auth-token/client/gettokenmsg.c
Normal file
793
CASA-auth-token/client/gettokenmsg.c
Normal 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);
|
||||
}
|
||||
|
||||
|
||||
//++=======================================================================
|
||||
//++=======================================================================
|
||||
//++=======================================================================
|
||||
|
||||
369
CASA-auth-token/client/internal.h
Normal file
369
CASA-auth-token/client/internal.h
Normal 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_
|
||||
|
||||
177
CASA-auth-token/client/mech_if.h
Normal file
177
CASA-auth-token/client/mech_if.h
Normal 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_
|
||||
|
||||
12
CASA-auth-token/client/mechanisms/krb5/Krb5Authenticate.conf
Normal file
12
CASA-auth-token/client/mechanisms/krb5/Krb5Authenticate.conf
Normal file
@@ -0,0 +1,12 @@
|
||||
#######################################################
|
||||
# #
|
||||
# CASA Authentication Token System configuration file #
|
||||
# for module: #
|
||||
# #
|
||||
# Krb5Authenticate #
|
||||
# #
|
||||
#######################################################
|
||||
|
||||
LibraryName \Program Files\novell\casa\lib\krb5mech.dll
|
||||
|
||||
|
||||
30
CASA-auth-token/client/mechanisms/krb5/README
Normal file
30
CASA-auth-token/client/mechanisms/krb5/README
Normal 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.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
14
CASA-auth-token/client/mechanisms/krb5/TODO
Normal file
14
CASA-auth-token/client/mechanisms/krb5/TODO
Normal 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.
|
||||
|
||||
207
CASA-auth-token/client/mechanisms/krb5/interface.c
Normal file
207
CASA-auth-token/client/mechanisms/krb5/interface.c
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
//++=======================================================================
|
||||
//++=======================================================================
|
||||
//++=======================================================================
|
||||
|
||||
90
CASA-auth-token/client/mechanisms/krb5/internal.h
Normal file
90
CASA-auth-token/client/mechanisms/krb5/internal.h
Normal 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_
|
||||
182
CASA-auth-token/client/mechanisms/krb5/krb5.vcproj
Normal file
182
CASA-auth-token/client/mechanisms/krb5/krb5.vcproj
Normal 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 \"Program Files"\novell\
|
||||
mkdir \"Program Files"\novell\casa
|
||||
mkdir \"Program Files"\novell\casa\lib\
|
||||
mkdir \"Program Files"\novell\casa\etc\
|
||||
mkdir \"Program Files"\novell\casa\etc\auth\
|
||||
mkdir \"Program Files"\novell\casa\etc\auth\mechanisms\
|
||||
copy Krb5Authenticate.conf \"Program Files"\novell\casa\etc\auth\mechanisms\Krb5Authenticate.conf
|
||||
copy $(OutDir)\krb5mech.dll \"Program Files"\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 \"Program Files"\novell\
|
||||
mkdir \"Program Files"\novell\casa
|
||||
mkdir \"Program Files"\novell\casa\lib\
|
||||
mkdir \"Program Files"\novell\casa\etc\
|
||||
mkdir \"Program Files"\novell\casa\etc\auth\
|
||||
mkdir \"Program Files"\novell\casa\etc\auth\mechanisms\
|
||||
copy Krb5Authenticate.conf \"Program Files"\novell\casa\etc\auth\mechanisms\Krb5Authenticate.conf
|
||||
copy $(OutDir)\krb5mech.dll \"Program Files"\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>
|
||||
282
CASA-auth-token/client/mechanisms/krb5/util.c
Normal file
282
CASA-auth-token/client/mechanisms/krb5/util.c
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
//++=======================================================================
|
||||
//++=======================================================================
|
||||
//++=======================================================================
|
||||
|
||||
132
CASA-auth-token/client/mechanisms/krb5/windows/dllsup.c
Normal file
132
CASA-auth-token/client/mechanisms/krb5/windows/dllsup.c
Normal 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);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
//=========================================================================
|
||||
|
||||
272
CASA-auth-token/client/mechanisms/krb5/windows/get.c
Normal file
272
CASA-auth-token/client/mechanisms/krb5/windows/get.c
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
//++=======================================================================
|
||||
//++=======================================================================
|
||||
//++=======================================================================
|
||||
|
||||
10
CASA-auth-token/client/mechanisms/krb5/windows/krb5mech.def
Normal file
10
CASA-auth-token/client/mechanisms/krb5/windows/krb5mech.def
Normal 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
|
||||
35
CASA-auth-token/client/mechanisms/krb5/windows/platform.c
Normal file
35
CASA-auth-token/client/mechanisms/krb5/windows/platform.c
Normal 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 ]==================================================
|
||||
|
||||
|
||||
83
CASA-auth-token/client/mechanisms/krb5/windows/platform.h
Normal file
83
CASA-auth-token/client/mechanisms/krb5/windows/platform.h
Normal 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_
|
||||
|
||||
12
CASA-auth-token/client/mechanisms/pwd/PwdAuthenticate.conf
Normal file
12
CASA-auth-token/client/mechanisms/pwd/PwdAuthenticate.conf
Normal file
@@ -0,0 +1,12 @@
|
||||
#######################################################
|
||||
# #
|
||||
# CASA Authentication Token System configuration file #
|
||||
# for module: #
|
||||
# #
|
||||
# PwdAuthenticate #
|
||||
# #
|
||||
#######################################################
|
||||
|
||||
LibraryName \Program Files\novell\casa\lib\pwmech.dll
|
||||
|
||||
|
||||
27
CASA-auth-token/client/mechanisms/pwd/README
Normal file
27
CASA-auth-token/client/mechanisms/pwd/README
Normal 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.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
14
CASA-auth-token/client/mechanisms/pwd/TODO
Normal file
14
CASA-auth-token/client/mechanisms/pwd/TODO
Normal 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.
|
||||
|
||||
359
CASA-auth-token/client/mechanisms/pwd/get.c
Normal file
359
CASA-auth-token/client/mechanisms/pwd/get.c
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
//++=======================================================================
|
||||
//++=======================================================================
|
||||
//++=======================================================================
|
||||
|
||||
207
CASA-auth-token/client/mechanisms/pwd/interface.c
Normal file
207
CASA-auth-token/client/mechanisms/pwd/interface.c
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
//++=======================================================================
|
||||
//++=======================================================================
|
||||
//++=======================================================================
|
||||
|
||||
92
CASA-auth-token/client/mechanisms/pwd/internal.h
Normal file
92
CASA-auth-token/client/mechanisms/pwd/internal.h
Normal 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_
|
||||
|
||||
183
CASA-auth-token/client/mechanisms/pwd/pwd.vcproj
Normal file
183
CASA-auth-token/client/mechanisms/pwd/pwd.vcproj
Normal 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 \"Program Files"\novell\
|
||||
mkdir \"Program Files"\novell\casa
|
||||
mkdir \"Program Files"\novell\casa\lib\
|
||||
mkdir \"Program Files"\novell\casa\etc\
|
||||
mkdir \"Program Files"\novell\casa\etc\auth\
|
||||
mkdir \"Program Files"\novell\casa\etc\auth\mechanisms\
|
||||
copy PwdAuthenticate.conf \"Program Files"\novell\casa\etc\auth\mechanisms\PwdAuthenticate.conf
|
||||
copy $(OutDir)\pwmech.dll \"Program Files"\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 \"Program Files"\novell\
|
||||
mkdir \"Program Files"\novell\casa
|
||||
mkdir \"Program Files"\novell\casa\lib\
|
||||
mkdir \"Program Files"\novell\casa\etc\
|
||||
mkdir \"Program Files"\novell\casa\etc\auth\
|
||||
mkdir \"Program Files"\novell\casa\etc\auth\mechanisms\
|
||||
copy PwdAuthenticate.conf \"Program Files"\novell\casa\etc\auth\mechanisms\PwdAuthenticate.conf
|
||||
copy $(OutDir)\pwmech.dll \"Program Files"\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>
|
||||
282
CASA-auth-token/client/mechanisms/pwd/util.c
Normal file
282
CASA-auth-token/client/mechanisms/pwd/util.c
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
//++=======================================================================
|
||||
//++=======================================================================
|
||||
//++=======================================================================
|
||||
|
||||
132
CASA-auth-token/client/mechanisms/pwd/windows/dllsup.c
Normal file
132
CASA-auth-token/client/mechanisms/pwd/windows/dllsup.c
Normal 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);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
//=========================================================================
|
||||
|
||||
35
CASA-auth-token/client/mechanisms/pwd/windows/platform.c
Normal file
35
CASA-auth-token/client/mechanisms/pwd/windows/platform.c
Normal 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 ]==================================================
|
||||
|
||||
|
||||
81
CASA-auth-token/client/mechanisms/pwd/windows/platform.h
Normal file
81
CASA-auth-token/client/mechanisms/pwd/windows/platform.h
Normal 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_
|
||||
|
||||
10
CASA-auth-token/client/mechanisms/pwd/windows/pwmech.def
Normal file
10
CASA-auth-token/client/mechanisms/pwd/windows/pwmech.def
Normal file
@@ -0,0 +1,10 @@
|
||||
LIBRARY PWMECH
|
||||
DESCRIPTION 'CASA PW Authentication Mechanism Library.'
|
||||
|
||||
|
||||
EXPORTS
|
||||
; DllRegisterServer PRIVATE
|
||||
; DllUnregisterServer PRIVATE
|
||||
; DllGetClassObject PRIVATE
|
||||
GetAuthTokenInterface PRIVATE
|
||||
; DllCanUnloadNow PRIVATE
|
||||
513
CASA-auth-token/client/test/CASA_Auth.cpp
Normal file
513
CASA-auth-token/client/test/CASA_Auth.cpp
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
142
CASA-auth-token/client/test/test.vcproj
Normal file
142
CASA-auth-token/client/test/test.vcproj
Normal 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=""C:\Program Files\novell\CASA\lib""
|
||||
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=""C:\Program Files\novell\CASA\lib""
|
||||
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>
|
||||
321
CASA-auth-token/client/util.c
Normal file
321
CASA-auth-token/client/util.c
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
//++=======================================================================
|
||||
//++=======================================================================
|
||||
//++=======================================================================
|
||||
|
||||
10
CASA-auth-token/client/windows/authtoken.def
Normal file
10
CASA-auth-token/client/windows/authtoken.def
Normal file
@@ -0,0 +1,10 @@
|
||||
LIBRARY AUTHTOKEN
|
||||
DESCRIPTION 'CASA Authentication Token Library.'
|
||||
|
||||
|
||||
EXPORTS
|
||||
; DllRegisterServer PRIVATE
|
||||
; DllUnregisterServer PRIVATE
|
||||
; DllGetClassObject PRIVATE
|
||||
ObtainAuthToken PRIVATE
|
||||
; DllCanUnloadNow PRIVATE
|
||||
1091
CASA-auth-token/client/windows/cache.c
Normal file
1091
CASA-auth-token/client/windows/cache.c
Normal file
File diff suppressed because it is too large
Load Diff
132
CASA-auth-token/client/windows/dllsup.c
Normal file
132
CASA-auth-token/client/windows/dllsup.c
Normal 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);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
//=========================================================================
|
||||
|
||||
549
CASA-auth-token/client/windows/platform.c
Normal file
549
CASA-auth-token/client/windows/platform.c
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
//++=======================================================================
|
||||
//++=======================================================================
|
||||
//++=======================================================================
|
||||
|
||||
114
CASA-auth-token/client/windows/platform.h
Normal file
114
CASA-auth-token/client/windows/platform.h
Normal 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 ]===============================================
|
||||
|
||||
//=========================================================================
|
||||
|
||||
498
CASA-auth-token/client/windows/rpc.c
Normal file
498
CASA-auth-token/client/windows/rpc.c
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
//++=======================================================================
|
||||
//++=======================================================================
|
||||
//++=======================================================================
|
||||
|
||||
187
CASA-auth-token/include/list_entry.h
Normal file
187
CASA-auth-token/include/list_entry.h
Normal 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_
|
||||
|
||||
|
||||
70
CASA-auth-token/include/proto.h
Normal file
70
CASA-auth-token/include/proto.h
Normal 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_
|
||||
37
CASA-auth-token/server/ApacheSupport/2.2/Makefile.am
Normal file
37
CASA-auth-token/server/ApacheSupport/2.2/Makefile.am
Normal file
@@ -0,0 +1,37 @@
|
||||
#######################################################################
|
||||
#
|
||||
# Copyright (C) 2006 Novell, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public
|
||||
# License along with this program; if not, write to the Free
|
||||
# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
# Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
SUBDIRS = $(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
|
||||
|
||||
108
CASA-auth-token/server/ApacheSupport/2.2/README
Normal file
108
CASA-auth-token/server/ApacheSupport/2.2/README
Normal 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.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
13
CASA-auth-token/server/ApacheSupport/2.2/TODO
Normal file
13
CASA-auth-token/server/ApacheSupport/2.2/TODO
Normal 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.
|
||||
111
CASA-auth-token/server/ApacheSupport/2.2/linux/Makefile.am
Normal file
111
CASA-auth-token/server/ApacheSupport/2.2/linux/Makefile.am
Normal file
@@ -0,0 +1,111 @@
|
||||
#######################################################################
|
||||
#
|
||||
# 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 =
|
||||
|
||||
CASAROOT = ../../../../..
|
||||
|
||||
CASALIBDIR = $(CASAROOT)/$(LIB)
|
||||
APACHEROOT = /home/jluciani/dev-local/apache2.2
|
||||
|
||||
# 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$(CASAROOT)/include -I$(APACHEROOT)/include
|
||||
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$(CASALIBDIR)/$(TARGET_CFG) -L$(APACHEROOT)/lib -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) $(CASALIBDIR)/$(TARGET_CFG)/$(MODULE_NAME).$(MODULE_EXT)
|
||||
|
||||
$(OBJDIR):
|
||||
[ -d $(OBJDIR) ] || mkdir -p $(OBJDIR)
|
||||
[ -d $(CASALIBDIR) ] || mkdir -p $(CASALIBDIR)
|
||||
[ -d $(CASALIBDIR)/$(TARGET_CFG) ] || mkdir -p $(CASALIBDIR)/$(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
|
||||
|
||||
478
CASA-auth-token/server/ApacheSupport/2.2/mod_authn_casa.c
Normal file
478
CASA-auth-token/server/ApacheSupport/2.2/mod_authn_casa.c
Normal 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
|
||||
};
|
||||
37
CASA-auth-token/server/ApacheSupport/Makefile.am
Normal file
37
CASA-auth-token/server/ApacheSupport/Makefile.am
Normal file
@@ -0,0 +1,37 @@
|
||||
#######################################################################
|
||||
#
|
||||
# Copyright (C) 2006 Novell, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public
|
||||
# License along with this program; if not, write to the Free
|
||||
# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
# Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
SUBDIRS = 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
|
||||
|
||||
42
CASA-auth-token/server/AuthTokenSvc/.project
Normal file
42
CASA-auth-token/server/AuthTokenSvc/.project
Normal file
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>CasaAuthServer</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.wst.common.project.facet.core.builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.wst.validation.validationbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jst.j2ee.ejb.annotations.xdoclet.xdocletbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
|
||||
<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
|
||||
</natures>
|
||||
<linkedResources>
|
||||
<link>
|
||||
<name>identity-abstraction.jar</name>
|
||||
<type>1</type>
|
||||
<location>/home/jluciani/dev-local/bandit/trunk/IdentityAbstraction/build/identity-abstraction.jar</location>
|
||||
</link>
|
||||
</linkedResources>
|
||||
</projectDescription>
|
||||
146
CASA-auth-token/server/AuthTokenSvc/Makefile.am
Normal file
146
CASA-auth-token/server/AuthTokenSvc/Makefile.am
Normal file
@@ -0,0 +1,146 @@
|
||||
#######################################################################
|
||||
#
|
||||
# Copyright (C) 2006 Novell, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public
|
||||
# License along with this program; if not, write to the Free
|
||||
# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
SUBDIRS =
|
||||
DIST_SUBDIRS = src src/com src/com/novell src/com/novell/casa src/com/novell/casa/authtoksvc
|
||||
|
||||
EXTRA_DIST = $(JAVAFILES)
|
||||
|
||||
CASAROOT = ../../..
|
||||
|
||||
CASALIBDIR = $(CASAROOT)/$(LIB)
|
||||
|
||||
IDENT_ABSTRACTION_DIR = /home/jluciani/dev-local/bandit/trunk/IdentityAbstraction/build
|
||||
IDENT_ABSTRACTION_DEPENDANCIES_DIR = /home/jluciani/dev-local/bandit/trunk/commons/bin
|
||||
|
||||
JAVAROOT = .
|
||||
JAVAC= javac
|
||||
|
||||
WEBAPP_NAME = CasaAuthTokenSvc
|
||||
WEBAPP_EXT = war
|
||||
MODULE_NAME = CasaAuthToken
|
||||
MODULE_EXT = jar
|
||||
|
||||
JAVAFILES = src/com/novell/casa/authtoksvc/ProtoDefs.java \
|
||||
src/com/novell/casa/authtoksvc/AuthMechConfig.java \
|
||||
src/com/novell/casa/authtoksvc/SvcConfig.java \
|
||||
src/com/novell/casa/authtoksvc/IdenTokenConfig.java \
|
||||
src/com/novell/casa/authtoksvc/AuthTokenConfig.java \
|
||||
src/com/novell/casa/authtoksvc/EnabledSvcsConfig.java \
|
||||
src/com/novell/casa/authtoksvc/AuthMechanism.java \
|
||||
src/com/novell/casa/authtoksvc/Authenticate.java \
|
||||
src/com/novell/casa/authtoksvc/RpcMethod.java \
|
||||
src/com/novell/casa/authtoksvc/Rpc.java \
|
||||
src/com/novell/casa/authtoksvc/GetAuthPolicy.java \
|
||||
src/com/novell/casa/authtoksvc/Base64Coder.java \
|
||||
src/com/novell/casa/authtoksvc/AuthReqMsg.java \
|
||||
src/com/novell/casa/authtoksvc/AuthRespMsg.java \
|
||||
src/com/novell/casa/authtoksvc/IdentityToken.java \
|
||||
src/com/novell/casa/authtoksvc/CasaIdentityToken.java \
|
||||
src/com/novell/casa/authtoksvc/AuthToken.java \
|
||||
src/com/novell/casa/authtoksvc/GetAuthPolicyReqMsg.java \
|
||||
src/com/novell/casa/authtoksvc/GetAuthPolicyRespMsg.java \
|
||||
src/com/novell/casa/authtoksvc/GetAuthToken.java \
|
||||
src/com/novell/casa/authtoksvc/GetAuthTokReqMsg.java \
|
||||
src/com/novell/casa/authtoksvc/GetAuthTokRespMsg.java \
|
||||
src/com/novell/casa/authtoksvc/Krb5Authenticate.java \
|
||||
src/com/novell/casa/authtoksvc/PwdAuthenticate.java \
|
||||
src/com/novell/casa/authtoksvc/SessionToken.java
|
||||
|
||||
BUILDDIR = build
|
||||
|
||||
WEBAPP = $(WEBAPP_NAME).$(WEBAPP_EXT)
|
||||
|
||||
#AUTHTOKEN_FILES = -C $(BUILDDIR)/webapp/WEB-INF/classes com/novell/casa/authtoksvc/AuthToken.class \
|
||||
# -C $(BUILDDIR)/webapp/WEB-INF/classes com/novell/casa/authtoksvc/AuthToken$SAXHandler.cless \
|
||||
# -C $(BUILDDIR)/webapp/WEB-INF/classes com/novell/casa/authtoksvc/AuthTokenConfig.class \
|
||||
# -C $(BUILDDIR)/webapp/WEB-INF/classes com/novell/casa/authtoksvc/AuthTokenConfig$SAXHandler.class \
|
||||
# -C $(BUILDDIR)/webapp/WEB-INF/classes com/novell/casa/authtoksvc/IdenTokenConfig.class \
|
||||
# -C $(BUILDDIR)/webapp/WEB-INF/classes com/novell/casa/authtoksvc/IdenTokenConfig$SAXHandler.class \
|
||||
# -C $(BUILDDIR)/webapp/WEB-INF/classes com/novell/casa/authtoksvc/IdentityToken.class \
|
||||
# -C $(BUILDDIR)/webapp/WEB-INF/classes com/novell/casa/authtoksvc/CasaIdentityToken.class \
|
||||
# -C $(BUILDDIR)/webapp/WEB-INF/classes com/novell/casa/authtoksvc/CasaIdentityToken$SAXHandler.class \
|
||||
# -C $(BUILDDIR)/webapp/WEB-INF/classes com/novell/casa/authtoksvc/Base64Coder.class
|
||||
AUTHTOKEN_FILES = -C $(BUILDDIR)/webapp/WEB-INF/classes com
|
||||
|
||||
CLASSES = $(addprefix $(BUILDDIR)/, $(JAVAFILES:%.java=%.class))
|
||||
|
||||
LIBS = /usr/share/java/servletapi5.jar
|
||||
CLASSPATH = $(IDENT_ABSTRACTION_DIR):$(LIBS)
|
||||
|
||||
CUR_DIR := $(shell pwd)
|
||||
|
||||
all: $(BUILDDIR)/$(WEBAPP) $(BUILDDIR)/$(MODULE_NAME).$(MODULE_EXT)
|
||||
|
||||
$(BUILDDIR)/%.class: %.java
|
||||
@echo [======== Compiling $@ ========]
|
||||
$(JAVAC) -sourcepath src -classpath $(CLASSPATH) -d $(BUILDDIR)/webapp/WEB-INF/classes $<
|
||||
|
||||
$(BUILDDIR)/$(WEBAPP): $(BUILDDIR) $(CLASSES)
|
||||
@echo [======== Creating Webapp $@ ========]
|
||||
cp web.xml $(BUILDDIR)/webapp/WEB-INF/web.xml
|
||||
cp svc.settings $(BUILDDIR)/webapp/WEB-INF/conf/svc.settings
|
||||
cp authtoken.settings $(BUILDDIR)/webapp/WEB-INF/conf/authtoken.settings
|
||||
cp identoken.settings $(BUILDDIR)/webapp/WEB-INF/conf/identoken.settings
|
||||
cp src/com/novell/casa/authtoksvc/Krb5_mechanism.settings $(BUILDDIR)/webapp/WEB-INF/conf/installed_auth_mechanisms/Krb5Authenticate/mechanism.settings
|
||||
cp src/com/novell/casa/authtoksvc/Pwd_mechanism.settings $(BUILDDIR)/webapp/WEB-INF/conf/installed_auth_mechanisms/PwdAuthenticate/mechanism.settings
|
||||
cp $(IDENT_ABSTRACTION_DIR)/*.jar $(BUILDDIR)/webapp/WEB-INF/lib/
|
||||
cp $(IDENT_ABSTRACTION_DEPENDANCIES_DIR)/*.jar $(BUILDDIR)/webapp/WEB-INF/lib/
|
||||
jar cvf $(BUILDDIR)/$(WEBAPP) -C $(BUILDDIR)/webapp .
|
||||
cp $(BUILDDIR)/$(WEBAPP) $(CASALIBDIR)/java/
|
||||
|
||||
$(BUILDDIR)/$(MODULE_NAME).$(MODULE_EXT): $(BUILDDIR) $(CLASSES)
|
||||
@echo [======== Jarring $@ ========]
|
||||
jar cvf $(BUILDDIR)/$(MODULE_NAME).$(MODULE_EXT) $(AUTHTOKEN_FILES)
|
||||
cp $(BUILDDIR)/$(MODULE_NAME).$(MODULE_EXT) $(CASALIBDIR)/java/
|
||||
|
||||
$(BUILDDIR):
|
||||
[ -d $(BUILDDIR) ] || mkdir -p $(BUILDDIR)
|
||||
[ -d $(BUILDDIR)/webapp ] || mkdir -p $(BUILDDIR)/webapp
|
||||
[ -d $(BUILDDIR)/webapp/WEB-INF ] || mkdir -p $(BUILDDIR)/webapp/WEB-INF
|
||||
[ -d $(BUILDDIR)/webapp/WEB-INF/classes ] || mkdir -p $(BUILDDIR)/webapp/WEB-INF/classes
|
||||
[ -d $(BUILDDIR)/webapp/WEB-INF/lib ] || mkdir -p $(BUILDDIR)/webapp/WEB-INF/lib
|
||||
[ -d $(BUILDDIR)/webapp/WEB-INF/conf ] || mkdir -p $(BUILDDIR)/webapp/WEB-INF/conf
|
||||
[ -d $(BUILDDIR)/webapp/WEB-INF/conf/enabled_services ] || mkdir -p $(BUILDDIR)/webapp/WEB-INF/conf/enabled_services
|
||||
[ -d $(BUILDDIR)/webapp/WEB-INF/conf/auth_mechanisms ] || mkdir -p $(BUILDDIR)/webapp/WEB-INF/conf/auth_mechanisms
|
||||
[ -d $(BUILDDIR)/webapp/WEB-INF/conf/installed_auth_mechanisms ] || mkdir -p $(BUILDDIR)/webapp/WEB-INF/conf/installed_auth_mechanisms
|
||||
[ -d $(BUILDDIR)/webapp/WEB-INF/conf/installed_auth_mechanisms/Krb5Authenticate ] || mkdir -p $(BUILDDIR)/webapp/WEB-INF/conf/installed_auth_mechanisms/Krb5Authenticate
|
||||
[ -d $(BUILDDIR)/webapp/WEB-INF/conf/installed_auth_mechanisms/PwdAuthenticate ] || mkdir -p $(BUILDDIR)/webapp/WEB-INF/conf/installed_auth_mechanisms/PwdAuthenticate
|
||||
[ -d $(CASALIBDIR) ] || mkdir -p $(CASALIBDIR)
|
||||
[ -d $(CASALIBDIR)/java ] || mkdir -p $(CASALIBDIR)/java
|
||||
|
||||
install-exec-local:
|
||||
|
||||
uninstall-local:
|
||||
|
||||
#installcheck-local: install
|
||||
|
||||
clean-local:
|
||||
if [ -d $(BUILDDIR) ]; then rm -rf $(BUILDDIR); fi
|
||||
if [ -f $(CASALIBDIR)/java/$(MODULE_NAME).$(MODULE_EXT) ]; then rm -f $(CASALIBDIR)/java/$(MODULE_NAME).$(MODULE_EXT); fi
|
||||
if [ -f $(CASALIBDIR)/java/$(WEBAPP) ]; then rm -f $(CASALIBDIR)/java/$(WEBAPP); fi
|
||||
|
||||
distclean-local:
|
||||
|
||||
maintainer-clean-local:
|
||||
rm -f Makefile.in
|
||||
rm -f Makefile
|
||||
|
||||
292
CASA-auth-token/server/AuthTokenSvc/README
Normal file
292
CASA-auth-token/server/AuthTokenSvc/README
Normal file
@@ -0,0 +1,292 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* README for AuthTokenSvc
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
INTRODUCTION
|
||||
|
||||
AuthTokenSvc is the CASA Authentication Token Service (ATS). It is implemented
|
||||
as a Java servlet and supporting classes that execute in the Tomcat environment.
|
||||
|
||||
The ATS is responsible for providing clients with the necessary authentication
|
||||
policy information, for authenticating client entities, and for providing
|
||||
clients with Authentication Tokens that they can then use for authenticating
|
||||
to CASA Authentication enabled services.
|
||||
|
||||
The ATS utilizes mechanism plug-ins for authenticating client entities as well
|
||||
Identity Token Providers for the generation of Identity Tokens.
|
||||
|
||||
ENVIRONMENT SETTINGS
|
||||
|
||||
The following options must be set in the JAVA_OPTS setting before starting Tomcat
|
||||
to allow the Kerberos authentication mechanism to work properly:
|
||||
|
||||
-Djavax.security.auth.useSubjectCredsOnly=false
|
||||
-Djava.security.auth.login.config={replace with the path for JAAS configuration
|
||||
file for the service}
|
||||
|
||||
After setting the above values in the JAVA_OPTS variable you must export it for
|
||||
Tomcat to be able to make use of it.
|
||||
|
||||
The following entry should be included in the JAAS configuration file specified
|
||||
in the java.security.auth.login.config option above to enable the Krb5 authentication
|
||||
mechanism to work correctly:
|
||||
|
||||
other {
|
||||
com.sun.security.auth.module.Krb5LoginModule required
|
||||
useTicketCache=true
|
||||
ticketCache="/var/cache/tomcat5/base/temp/ticket.cache"
|
||||
useKeyTab=true
|
||||
principal="host/server.company.com"
|
||||
doNotPrompt=true
|
||||
storeKey=true
|
||||
keyTab="/etc/krb5.keytab";
|
||||
}
|
||||
|
||||
Please adjust the ticketCache and principal setting to match your installation.
|
||||
|
||||
CONFIGURATION
|
||||
|
||||
AuthTokenSvc configuration consists of multiple entities. Most of the AuthTokenSvc
|
||||
configuration is contained within the "conf" folder under the WEB-INF folder of the
|
||||
application. For an example configuration setup for the AuthTokenSvc see the
|
||||
sampleConf folder.
|
||||
|
||||
The location of the AuthTokenSvc configuration folder can be over-ridden by specifying
|
||||
a different path via the com.novell.casa.authtoksvc.config system property.
|
||||
|
||||
CONFIGURING THE BASE SERVICE
|
||||
|
||||
The ATS base settings are configured in the svc.settings file under the conf folder.
|
||||
|
||||
Thhe following is an example svc.settings file:
|
||||
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<settings>
|
||||
<SessionTokenLifetime>43200</SessionTokenLifetime>
|
||||
<LifetimeShorter>10</LifetimeShorter>
|
||||
<IAConfigFile>/home/jluciani/jakarta-tomcat-5.0.28/webapps/CasaAuthTokenSvc/WEB-INF/conf/iaRealms.xml</IAConfigFile>
|
||||
<ReconfigureInterval>60</ReconfigureInterval>
|
||||
<startSearchContext>o=novell</startSearchContext>
|
||||
</settings>
|
||||
|
||||
Note the following about the sample svc.settings file:
|
||||
|
||||
- The settngs that you can specify in the svc.settings file are: SessionLifetime,
|
||||
LifetimeShorter, IAConfigFile, and startSearchContext.
|
||||
|
||||
- The SessionTokenLifetime setting specifies the number of seconds for which a
|
||||
session token is good for after being issued. The default value for this setting
|
||||
is 43200 seconds. Note that a larger value reduces overhead.
|
||||
|
||||
- The LifetimeShorter setting specifies the number of seconds that should be substracted
|
||||
from the SessionTokenLifetime when calculating the number of seconds that clients are
|
||||
told that the session tokens are good for. The default value for this setting is 5
|
||||
seconds.
|
||||
|
||||
- The IAConfigFile settings specifies the path to the identity abstraction
|
||||
configuration file. The identity abstraction configuration file configures
|
||||
the different realms (contexts) that the ATS can utilize to authenticate
|
||||
entities and resolve identities. In the future the configuration of this
|
||||
settng will be optional.
|
||||
|
||||
- The ReconfigureInterval setting specifies how often the ATS should refresh its
|
||||
configuration. The default value for this setting is 60 seconds. A ReconfigureInterval
|
||||
value of 0 means that the ATS will not refresh its configuration once it has been
|
||||
initialized, thus requiring that the servlet be re-initialized to make configuration
|
||||
changes take effect.
|
||||
|
||||
- The startSearchContext setting specifies the begin location for initiating
|
||||
context searches. The absence of this setting will result in searches ocurring
|
||||
from the root of the tree. This setting or an equivalent setting will be moved
|
||||
to the identity abstraction configuration file where it belongs. Once this is done,
|
||||
the setting will no longer be recognized within the svc.settings file.
|
||||
|
||||
CONFIGURING SERVICES TO CONSUME CASA AUTHENTICATION TOKENS
|
||||
|
||||
Services are configured to consume CASA authentication tokens by creating folders
|
||||
under the conf/enabled_services folders. Since CASA distinguishes between services
|
||||
of the same name existing in different hosts, the first folder that must be created
|
||||
is one for the host where the service resides. The host folder name must match the
|
||||
DNS name of the host where the service resides. Services are configured by creating
|
||||
a folder under the appropriate host folder with a name matching the service name.
|
||||
|
||||
Note when configuring services that the service name and the host names must match
|
||||
the service and host names specified by the client applications when requesting
|
||||
tokens to authenticate to them.
|
||||
|
||||
The services folder must contain an auth.policy file, an authtoken.settings file,
|
||||
and an identoken.settings file. In the absence of any one of those files, the ATS
|
||||
will default to utilizing the files present under its conf folder.
|
||||
|
||||
The auth.policy file specifies the authentication realms (or contexts) to which
|
||||
entities can authenticate to gain access to the service. The auth.policy file also
|
||||
specifies the authentication mechanisms that can be utilized to authenticate to the
|
||||
realms.
|
||||
|
||||
The following is an example auth.policy file:
|
||||
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<auth_policy>
|
||||
<auth_source>
|
||||
<realm>CorpTree</realm>
|
||||
<mechanism>Krb5Authenticate</mechanism>
|
||||
<mechanism_info>host@tokenserver.company.novell.com</mechanism_info>
|
||||
</auth_source>
|
||||
<auth_source>
|
||||
<realm>CorpTree</realm>
|
||||
<mechanism>PwdAuthenticate</mechanism>
|
||||
<mechanism_info></mechanism_info>
|
||||
</auth_source>
|
||||
</auth_policy>
|
||||
|
||||
Note the following about the sample auth.policy file:
|
||||
|
||||
- An authentication realm is specified in the auth.policy file by creating an
|
||||
auth_policy entry for it. An auth_policy entry must contain the realm name along
|
||||
with the entries for the authentication mechanisms.
|
||||
|
||||
- When a realm supports more than one authentication mechanism, you must create
|
||||
an auth_source entry for each supported mechanism.
|
||||
|
||||
- The realm names correspond to the realmIDs configured in the Identity Abstraction
|
||||
configuration file for the desired context entry.
|
||||
|
||||
- The authentication mechanism entries are: mechanism and mechanism_info. The mechanism
|
||||
entry specifies the name of the authentication mechanism. The mechanism_info specifies
|
||||
some mechanism specific information. Both authentication mechanism entries must be
|
||||
specified for an auth_source entry.
|
||||
|
||||
- The name of the Krb5 Authentication mechanism is "Krb5Authenticate". This mechanism
|
||||
requires that you specify the service's kerberos principal name under the mechanism_info
|
||||
key.
|
||||
|
||||
- The name of the username/password authentication mechanism is "PwdAuthenticate" and
|
||||
it does not require any information to be included under the mechanism_info key.
|
||||
|
||||
The authtoken.settings file contains settings that should be applied to authentication
|
||||
tokens issued to authenticate to the service.
|
||||
|
||||
The following is an example authtoken.settings file:
|
||||
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<settings>
|
||||
<TokenLifetime>3600</TokenLifetime>
|
||||
<LifetimeShorter>10</LifetimeShorter>
|
||||
<IdentityTokenType>CasaIdentityToken</IdentityTokenType>
|
||||
</settings>
|
||||
|
||||
Note the following about the sample authtoken.settings file:
|
||||
|
||||
- The settings that you can specify in the authtoken.settings file are: TokenLifetime,
|
||||
LifetimeShorter, and IdentityTokenType. If one of this tokens is not specified then
|
||||
its default value is utilized.
|
||||
|
||||
- The TokenLifetime setting specifies the number of seconds for which a token is good
|
||||
for after being issued. The default value for this setting is 3600 seconds. Note that
|
||||
a larger value reduces overhead, but it also gives more time for an intruder to
|
||||
utilize the token if it becomes compromized.
|
||||
|
||||
- The LifetimeShorter setting specifies the number of seconds that should be substracted
|
||||
from the TokenLifetime when calculating the number of seconds that clients are told
|
||||
that the tokens are good for. The default value for this setting is 5 seconds.
|
||||
|
||||
- The IdentityTokenType specifies the type of identity tokens that must be embedded in
|
||||
the authentication tokens with identity information. The default value for this
|
||||
setting is CasaIdentityToken.
|
||||
|
||||
The identoken.settings file contains settings that should be applied to identity tokens
|
||||
embedded in authentication tokens.
|
||||
|
||||
The following is an example identoken.settings file:
|
||||
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<settings>
|
||||
<Attributes>sn,groupMembership,guid</Attributes>
|
||||
<EncryptAttributes>false</EncryptAttributes>
|
||||
<Certificate>Base64 encoded certificate</Certificate>
|
||||
</settings>
|
||||
|
||||
Note the following about the sample identoken.settings file:
|
||||
|
||||
- The settings that you can specify in the identoken.settings file are: Attributes.
|
||||
EncryptAttributes, and Certificate.
|
||||
|
||||
- The Attributes setting specifies the identity attributes that must be included
|
||||
as part of the identity token, The attributes are specified in the form of a coma
|
||||
delimited list. The default velue for this setting is "sn".
|
||||
|
||||
- The EncryptAtributes setting specifies whether or not the identity information
|
||||
contained in the identity token should be emcrypted with the services's Public
|
||||
Certificate. The default value for this setting is "false". Please note that
|
||||
to enable identity attribute encryption you must not allow the ATS to default to
|
||||
the file present in its conf folder (Attribute encryption is not yet supported
|
||||
by the Casa identity token provider).
|
||||
|
||||
- The Certificate setting specifies the certificate that must be utilized to encrypt
|
||||
identity attribute data. The certificate contains the public key of the targeted
|
||||
service. The certificate data is Base64 encoded.
|
||||
|
||||
- The identoken.settings file can also contain additional identity token provider
|
||||
specific settings.
|
||||
|
||||
CONFIGURING AUTHENTICATION MECHANISMS
|
||||
|
||||
Authentication mechanisms available to the AuthTokenSvc are configured by creating
|
||||
a sub-folder named after the authentication mechanism type under the
|
||||
conf/auth_mechanisms folder. The authentication mechanism folders must contain a
|
||||
settings file named mechanism.settings. The mechanism.settings file must contain the
|
||||
name of the class implementing the mechanism along with path information which
|
||||
can be utilized by the ATS to load the class. The mechanism.settings file can
|
||||
also contain mechanism specific settings.
|
||||
|
||||
The following setting is mandatory:
|
||||
|
||||
ClassName - This is the name of the class implementing the authentication mechanism.
|
||||
|
||||
One of the following settings must be included:
|
||||
|
||||
RelativeClassPath - This is a relative path from the web application's root folder
|
||||
to the folder containing the class implementing the mechanism.
|
||||
|
||||
ClassPath - This is an absolute path to the folder containing the path to the class
|
||||
implementing the mechanism.
|
||||
|
||||
The following is an example mechanism.settings file for the Krb5Authentication
|
||||
mechanism:
|
||||
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<settings>
|
||||
<ClassName>com.novell.casa.authtoksvc.Krb5Authenticate</ClassName>
|
||||
<RelativeClassPath>WEB-INF/classes</RelativeClassPath>
|
||||
<ServicePrincipalName>host@authtokenserver.company.com</ServicePrincipalName>
|
||||
</settings>
|
||||
|
||||
The base AuthTokenSvc package contains two authentication mechanisms, these are
|
||||
Krb5Authenticate and PwdAuthenticate. The configuration under sampleConf is set up
|
||||
to allow an AuthTokenSvc to leverage both mechanisms.
|
||||
|
||||
The Krb5Authenticate mechanism requires that the following setting also be included
|
||||
in its mechanism.settings file:
|
||||
|
||||
ServicePrincipalName - This is the name of the Kerberos Service Principal that the
|
||||
Authentication Token Service runs as when authenticating other entities.
|
||||
|
||||
CONFIGURING ADDITIONAL IDENTITY TOKEN PROVIDERS
|
||||
|
||||
- TBD -
|
||||
|
||||
SECURITY CONSIDERATIONS
|
||||
|
||||
- TBD -
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
21
CASA-auth-token/server/AuthTokenSvc/TODO
Normal file
21
CASA-auth-token/server/AuthTokenSvc/TODO
Normal file
@@ -0,0 +1,21 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* TODO for AuthTokenSvc
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
INTRODUCTION
|
||||
|
||||
This file contains a list of the items still outstanding for AuthTokenSvc.
|
||||
|
||||
OUTSTANDING ITEMS
|
||||
|
||||
- Switch to a Web Services model where the Client/Server protocol uses SOAP.
|
||||
- Switch to use WS-Security, WS-Policy, and WS-Conversation for Authentication Tokens and Session Tokens.
|
||||
- Add code to verify that client/server communications occur over HTTPS.
|
||||
- Add logging.
|
||||
- Create plug-in API for Identity Token Providers.
|
||||
- Integrate into CASA build environment.
|
||||
- Review Code.
|
||||
- Change printfs used for debugging into a suitable mechanism.
|
||||
|
||||
4
CASA-auth-token/server/AuthTokenSvc/authtoken.settings
Normal file
4
CASA-auth-token/server/AuthTokenSvc/authtoken.settings
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<settings>
|
||||
<TokenLifetime>3600</TokenLifetime>
|
||||
</settings>
|
||||
6
CASA-auth-token/server/AuthTokenSvc/identoken.settings
Normal file
6
CASA-auth-token/server/AuthTokenSvc/identoken.settings
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<settings>
|
||||
<EncryptAttributes>false</EncryptAttributes>
|
||||
<Attributes>sn</Attributes>
|
||||
</settings>
|
||||
|
||||
13
CASA-auth-token/server/AuthTokenSvc/sampleConf/auth.policy
Normal file
13
CASA-auth-token/server/AuthTokenSvc/sampleConf/auth.policy
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<auth_policy>
|
||||
<auth_source>
|
||||
<realm>CorpTree</realm>
|
||||
<mechanism>Krb5Authenticate</mechanism>
|
||||
<mechanism_info>host@authtokenserver.company.com</mechanism_info>
|
||||
</auth_source>
|
||||
<auth_source>
|
||||
<realm>CorpTree</realm>
|
||||
<mechanism>PwdAuthenticate</mechanism>
|
||||
<mechanism_info></mechanism_info>
|
||||
</auth_source>
|
||||
</auth_policy>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<settings>
|
||||
<ClassName>com.novell.casa.authtoksvc.Krb5Authenticate</ClassName>
|
||||
<RelativeClassPath>WEB-INF/classes</RelativeClassPath>
|
||||
<ServicePrincipalName>host@tokenserver.company.novell.com</ServicePrincipalName>
|
||||
</settings>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<settings>
|
||||
<ClassName>com.novell.casa.authtoksvc.PwdAuthenticate</ClassName>
|
||||
<RelativeClassPath>WEB-INF/classes</RelativeClassPath>
|
||||
</settings>
|
||||
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<settings>
|
||||
<TokenLifetime>3600</TokenLifetime>
|
||||
</settings>
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<auth_policy>
|
||||
<auth_source>
|
||||
<realm>CorpTree</realm>
|
||||
<mechanism>Krb5Authenticate</mechanism>
|
||||
<mechanism_info>host@tokenserver.company.novell.com</mechanism_info>
|
||||
</auth_source>
|
||||
<auth_source>
|
||||
<realm>CorpTree</realm>
|
||||
<mechanism>PwdAuthenticate</mechanism>
|
||||
<mechanism_info></mechanism_info>
|
||||
</auth_source>
|
||||
</auth_policy>
|
||||
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<settings>
|
||||
<TokenLifetime>3600</TokenLifetime>
|
||||
</settings>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<settings>
|
||||
<EncryptAttributes>false</EncryptAttributes>
|
||||
<Attributes>sn,groupMembership</Attributes>
|
||||
</settings>
|
||||
|
||||
25
CASA-auth-token/server/AuthTokenSvc/sampleConf/iaRealms.xml
Normal file
25
CASA-auth-token/server/AuthTokenSvc/sampleConf/iaRealms.xml
Normal file
@@ -0,0 +1,25 @@
|
||||
<bci:realms
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:bci="http://www.bandit-project.org/commonidentity"
|
||||
xmlns:xacml="urn:oasis:names:tc:xacml:2.0:policy:schema:os"
|
||||
xsi:schemaLocation="urn:oasis:names:tc:xacml:2.0:policy:schema:os:access_control-xacml-2.0-policy-schema-os.xsd">
|
||||
<bci:realm
|
||||
desc="My Corporate Directory"
|
||||
connectorType="org.bandit.ia.connectors.LDAPConnectorInitialCtxFactory"
|
||||
id="jctree">
|
||||
<bci:connection xsi:type="bci:LDAPConnector">
|
||||
<bci:address>ldap://dirserver.companyname.com:389</bci:address>
|
||||
<bci:security>
|
||||
<bci:authentication>simple</bci:authentication>
|
||||
<bci:principal>cn=admin,o=companyname</bci:principal>
|
||||
<bci:credentials>password</bci:credentials>
|
||||
</bci:security>
|
||||
</bci:connection>
|
||||
</bci:realm>
|
||||
<bci:realm desc="Realm Join Definition" id="E263CCC1-8F9D-4551-B786-068AA84E8564">
|
||||
<bci:connection xsi:type="bci:JoinConnector">
|
||||
<bci:realmID>CorpTree</bci:realmID>
|
||||
</bci:connection>
|
||||
</bci:realm>
|
||||
</bci:realms>
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<settings>
|
||||
<EncryptAttributes>false</EncryptAttributes>
|
||||
<Attributes>sn</Attributes>
|
||||
</settings>
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<settings>
|
||||
<IAConfigFile>/home/jluciani/jakarta-tomcat-5.0.28/webapps/CasaAuthTokenSvc/WEB-INF/conf/iaRealms.xml</IAConfigFile>
|
||||
<SessionTokenLifetime>43200</SessionTokenLifetime>
|
||||
</settings>
|
||||
@@ -0,0 +1,258 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail,
|
||||
* you may find current contact information at www.novell.com.
|
||||
*
|
||||
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
package com.novell.casa.authtoksvc;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.XMLReader;
|
||||
import org.xml.sax.helpers.XMLReaderFactory;
|
||||
|
||||
/**
|
||||
* AuthMechConfig Class.
|
||||
*
|
||||
* This class obtains and maintains authentication token configuration.
|
||||
*
|
||||
*/
|
||||
public class AuthMechConfig
|
||||
{
|
||||
// Well known authentication token configuration settings
|
||||
public final static String ClassName = "ClassName";
|
||||
public final static String RelativeClassPath = "RelativeClassPath";
|
||||
public final static String ClassPath = "ClassPath";
|
||||
|
||||
private Map m_mechSettingsMap;
|
||||
|
||||
/*
|
||||
* Class for handling parsing events.
|
||||
*/
|
||||
private class SAXHandler extends org.xml.sax.helpers.DefaultHandler
|
||||
{
|
||||
private final static int AWAITING_ROOT_ELEMENT_START = 0;
|
||||
private final static int AWAITING_SETTING_ELEMENT_START = 1;
|
||||
private final static int AWAITING_SETTING_ELEMENT_DATA = 2;
|
||||
private final static int AWAITING_SETTING_ELEMENT_END = 3;
|
||||
private final static int DONE_PARSING = 4;
|
||||
|
||||
private final static String m_rootElementName = "settings";
|
||||
|
||||
private Map m_keyMap;
|
||||
private int m_state;
|
||||
private String m_currentKey;
|
||||
|
||||
/*
|
||||
* Constructor
|
||||
*/
|
||||
public SAXHandler(Map keyMap)
|
||||
{
|
||||
super();
|
||||
|
||||
// Initialize our members
|
||||
m_keyMap = keyMap;
|
||||
m_state = AWAITING_ROOT_ELEMENT_START;
|
||||
}
|
||||
|
||||
/*
|
||||
* endDocument() implementation.
|
||||
*/
|
||||
public void endDocument () throws SAXException
|
||||
{
|
||||
// Verify that we are not in an invalid state
|
||||
if (m_state != DONE_PARSING)
|
||||
{
|
||||
System.err.println("AuthMechConfig SAXHandler.endDocument()- Invalid state" + m_state);
|
||||
throw new SAXException("Invalid state at endDocument");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* startElement() implementation.
|
||||
*/
|
||||
public void startElement (String uri, String name, String qName, org.xml.sax.Attributes atts) throws SAXException
|
||||
{
|
||||
// Proceed based on our state
|
||||
switch (m_state)
|
||||
{
|
||||
case AWAITING_ROOT_ELEMENT_START:
|
||||
// Verify that we are processing the expected tag
|
||||
if (m_rootElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_SETTING_ELEMENT_START;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("AuthMechConfig SAXHandler.startElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_SETTING_ELEMENT_START:
|
||||
// Keep track of the key name
|
||||
m_currentKey = qName;
|
||||
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_SETTING_ELEMENT_DATA;
|
||||
break;
|
||||
|
||||
default:
|
||||
System.err.println("AuthMechConfig SAXHandler.startElement()- Invalid state " + m_state);
|
||||
throw new SAXException("Invalid state at startElement");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* endElement() immplementation.
|
||||
*/
|
||||
public void endElement (String uri, String name, String qName) throws SAXException
|
||||
{
|
||||
// Proceed based on our state
|
||||
switch (m_state)
|
||||
{
|
||||
case AWAITING_SETTING_ELEMENT_DATA:
|
||||
case AWAITING_SETTING_ELEMENT_END:
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_SETTING_ELEMENT_START;
|
||||
break;
|
||||
|
||||
case AWAITING_SETTING_ELEMENT_START:
|
||||
// Verify that we are processing the expected tag
|
||||
if (m_rootElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = DONE_PARSING;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("AuthMechConfig SAXHandler.endElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
System.err.println("AuthMechConfig SAXHandler.endElement()- Invalid state " + m_state);
|
||||
throw new SAXException("Invalid state at endElement");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* character() implementation.
|
||||
*/
|
||||
public void characters (char ch[], int start, int length) throws SAXException
|
||||
{
|
||||
// Consume the data if in the right state
|
||||
if (m_state == AWAITING_SETTING_ELEMENT_DATA)
|
||||
{
|
||||
// Consume the data and add the key to map
|
||||
m_keyMap.put(m_currentKey, new String(ch, start, length));
|
||||
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_SETTING_ELEMENT_END;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor which sets default configuration values.
|
||||
*/
|
||||
public AuthMechConfig() throws Exception
|
||||
{
|
||||
System.err.println("AuthMechConfig()- Default");
|
||||
|
||||
// Create a map to keep track of the token settings
|
||||
m_mechSettingsMap = new HashMap();
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor.
|
||||
*/
|
||||
public AuthMechConfig(String mechSettingsFileName) throws Exception
|
||||
{
|
||||
System.err.println("AuthMechConfig()-");
|
||||
|
||||
// Create a map to keep track of the token settings
|
||||
m_mechSettingsMap = new HashMap();
|
||||
|
||||
try
|
||||
{
|
||||
// Get an input stream to read from the token settings file
|
||||
File f = new File(mechSettingsFileName);
|
||||
FileInputStream inStream = new FileInputStream(f);
|
||||
|
||||
// Parse the file
|
||||
XMLReader xr = XMLReaderFactory.createXMLReader();
|
||||
SAXHandler handler = new SAXHandler(m_mechSettingsMap);
|
||||
xr.setContentHandler(handler);
|
||||
xr.setErrorHandler(handler);
|
||||
|
||||
InputSource source = new InputSource(inStream);
|
||||
xr.parse(source);
|
||||
|
||||
inStream.close();
|
||||
}
|
||||
catch (SAXException e)
|
||||
{
|
||||
System.err.println("AuthMechConfig()- " + mechSettingsFileName + " format error, exception: " + e.toString());
|
||||
throw new Exception("AuthMechConfig()- authtoken.settings format error");
|
||||
}
|
||||
catch (SecurityException e)
|
||||
{
|
||||
System.err.println("AuthMechConfig()- SecurityException accessing " + mechSettingsFileName + " Exception=" + e.toString());
|
||||
throw new Exception("AuthMechConfig()- Not able to access file");
|
||||
}
|
||||
catch (FileNotFoundException e)
|
||||
{
|
||||
System.err.println("AuthMechConfig()- File " + mechSettingsFileName + " not found");
|
||||
throw new Exception("AuthMechConfig()- File not found");
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
System.err.println("AuthMechConfig()- IOException accessing " + mechSettingsFileName + " Exception=" + e.toString());
|
||||
throw new Exception("AuthMechConfig()- Read error");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the value associated with the specified setting.
|
||||
*/
|
||||
public String getSetting(String settingName) throws Exception
|
||||
{
|
||||
// Try to find the setting in our map
|
||||
String value = (String) m_mechSettingsMap.get(settingName);
|
||||
if (value == null)
|
||||
{
|
||||
System.err.println("AuthMechConfig.getSetting()- Did not find setting " + settingName);
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("AuthMechConfig.getSetting()- Found setting " + settingName);
|
||||
System.err.println("AuthMechConfig.getSetting()- Setting value = " + value);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail,
|
||||
* you may find current contact information at www.novell.com.
|
||||
*
|
||||
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
package com.novell.casa.authtoksvc;
|
||||
|
||||
/*
|
||||
* AuthMechanism Interface.
|
||||
*
|
||||
* This is the interface implemented by Authentication Mechanisms.
|
||||
*
|
||||
* Please note that Authentication Machanisms must also implement the
|
||||
* Serializable interface.
|
||||
*
|
||||
*/
|
||||
public interface AuthMechanism
|
||||
{
|
||||
/*
|
||||
* Initialize the authentication mechanism.
|
||||
*/
|
||||
void init(SvcConfig svcConfig, AuthMechConfig mechConfig) throws Exception;
|
||||
|
||||
/*
|
||||
* Process authenticate request. If successful, return the Id of the
|
||||
* authenticated identity.
|
||||
*/
|
||||
String invoke(AuthReqMsg authReqMsg) throws Exception;
|
||||
|
||||
/*
|
||||
* Return the mechanism id.
|
||||
*/
|
||||
String getId();
|
||||
}
|
||||
@@ -0,0 +1,328 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail,
|
||||
* you may find current contact information at www.novell.com.
|
||||
*
|
||||
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
package com.novell.casa.authtoksvc;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.XMLReader;
|
||||
import org.xml.sax.helpers.XMLReaderFactory;
|
||||
|
||||
|
||||
/**
|
||||
* AuthReqMsg Class.
|
||||
*
|
||||
* This class deals with the message sent by Casa Client when requesting
|
||||
* that an entity be authenticated. The format of the message is as
|
||||
* follows:
|
||||
*
|
||||
* <?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
* <auth_req>
|
||||
* <realm>realm value</realm>
|
||||
* <mechanism>mechanism id</mechanism>
|
||||
* <auth_mech_token>mechanism token data</auth_mech_token>
|
||||
* </auth_req>
|
||||
*
|
||||
*/
|
||||
public class AuthReqMsg
|
||||
{
|
||||
|
||||
protected String m_realm = null;
|
||||
protected String m_authMechToken = null;
|
||||
protected String m_authMechanism = null;
|
||||
|
||||
/*
|
||||
* Class for handling Authentication Request parsing events.
|
||||
*/
|
||||
private class SAXHandler extends org.xml.sax.helpers.DefaultHandler
|
||||
{
|
||||
private final static int AWAITING_ROOT_ELEMENT_START = 0;
|
||||
private final static int AWAITING_ROOT_ELEMENT_END = 1;
|
||||
private final static int AWAITING_REALM_ELEMENT_START = 2;
|
||||
private final static int AWAITING_REALM_ELEMENT_END = 3;
|
||||
private final static int AWAITING_REALM_DATA = 4;
|
||||
private final static int AWAITING_MECH_ELEMENT_START = 5;
|
||||
private final static int AWAITING_MECH_ELEMENT_END = 6;
|
||||
private final static int AWAITING_MECH_DATA = 7;
|
||||
private final static int AWAITING_AUTH_MECH_TOKEN_ELEMENT_START = 8;
|
||||
private final static int AWAITING_AUTH_MECH_TOKEN_ELEMENT_END = 9;
|
||||
private final static int AWAITING_AUTH_MECH_TOKEN_DATA = 10;
|
||||
private final static int DONE_PARSING = 11;
|
||||
|
||||
private AuthReqMsg m_authReqMsg;
|
||||
private int m_state;
|
||||
|
||||
/*
|
||||
* Constructor
|
||||
*/
|
||||
public SAXHandler (AuthReqMsg authReqMsg)
|
||||
{
|
||||
super();
|
||||
|
||||
// Initialize our members
|
||||
m_authReqMsg = authReqMsg;
|
||||
m_state = AWAITING_ROOT_ELEMENT_START;
|
||||
}
|
||||
|
||||
/*
|
||||
* endDocument() implementation.
|
||||
*/
|
||||
public void endDocument () throws SAXException
|
||||
{
|
||||
// Verify that we obtained all of the required elements
|
||||
if (m_state != DONE_PARSING)
|
||||
{
|
||||
System.err.println("AuthReqMsg SAXHandler.endDocument()- Missing element");
|
||||
throw new SAXException("Missing element");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* startElement() implementation.
|
||||
*/
|
||||
public void startElement (String uri, String name, String qName, org.xml.sax.Attributes atts) throws SAXException
|
||||
{
|
||||
// Proceed based on our state
|
||||
switch (m_state)
|
||||
{
|
||||
case AWAITING_ROOT_ELEMENT_START:
|
||||
// Verify that we are processing the expected tag
|
||||
if (ProtoDefs.authRequestElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_REALM_ELEMENT_START;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("AuthReqMsg SAXHandler.startElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_REALM_ELEMENT_START:
|
||||
// Verify that we are processing the expected tag
|
||||
if (ProtoDefs.realmElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_REALM_DATA;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("AuthReqMsg SAXHandler.startElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_MECH_ELEMENT_START:
|
||||
// Verify that we are processing the expected tag
|
||||
if (ProtoDefs.mechanismElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_MECH_DATA;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("AuthReqMsg SAXHandler.startElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_AUTH_MECH_TOKEN_ELEMENT_START:
|
||||
// Verify that we are processing the expected tag
|
||||
if (ProtoDefs.authMechTokenElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_AUTH_MECH_TOKEN_DATA;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("AuthReqMsg SAXHandler.startElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
System.err.println("AuthReqMsg SAXHandler.startElement()- State error");
|
||||
throw new SAXException("State error");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* endElement() immplementation.
|
||||
*/
|
||||
public void endElement (String uri, String name, String qName) throws SAXException
|
||||
{
|
||||
// Proceed based on our state
|
||||
switch (m_state)
|
||||
{
|
||||
case AWAITING_ROOT_ELEMENT_END:
|
||||
// Verify that we are processing the expected tag
|
||||
if (ProtoDefs.authRequestElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = DONE_PARSING;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("AuthReqMsg SAXHandler.endElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_REALM_ELEMENT_END:
|
||||
// Verify that we are processing the expected tag
|
||||
if (ProtoDefs.realmElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_MECH_ELEMENT_START;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("AuthReqMsg SAXHandler.endElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_MECH_ELEMENT_END:
|
||||
// Verify that we are processing the expected tag
|
||||
if (ProtoDefs.mechanismElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_AUTH_MECH_TOKEN_ELEMENT_START;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("AuthReqMsg SAXHandler.endElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_AUTH_MECH_TOKEN_ELEMENT_END:
|
||||
// Verify that we are processing the expected tag
|
||||
if (ProtoDefs.authMechTokenElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_ROOT_ELEMENT_END;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("AuthReqMsg SAXHandler.endElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
System.err.println("AuthReqMsg SAXHandler.startElement()- State error");
|
||||
throw new SAXException("State error");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* character() implementation.
|
||||
*/
|
||||
public void characters (char ch[], int start, int length) throws SAXException
|
||||
{
|
||||
// Proceed based on our state
|
||||
switch (m_state)
|
||||
{
|
||||
case AWAITING_REALM_DATA:
|
||||
// Consume the data
|
||||
m_authReqMsg.m_realm = new String(ch, start, length);
|
||||
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_REALM_ELEMENT_END;
|
||||
break;
|
||||
|
||||
case AWAITING_MECH_DATA:
|
||||
// Consume the data
|
||||
m_authReqMsg.m_authMechanism = new String(ch, start, length);
|
||||
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_MECH_ELEMENT_END;
|
||||
break;
|
||||
|
||||
case AWAITING_AUTH_MECH_TOKEN_DATA:
|
||||
// Consume the data
|
||||
m_authReqMsg.m_authMechToken = new String(ch, start, length);
|
||||
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_AUTH_MECH_TOKEN_ELEMENT_END;
|
||||
break;
|
||||
|
||||
default:
|
||||
// Do nothing
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor
|
||||
*/
|
||||
public AuthReqMsg (InputStream inStream) throws Exception
|
||||
{
|
||||
try
|
||||
{
|
||||
// Parse the AuthReqMsg
|
||||
XMLReader xr = XMLReaderFactory.createXMLReader();
|
||||
SAXHandler handler = new SAXHandler(this);
|
||||
xr.setContentHandler(handler);
|
||||
xr.setErrorHandler(handler);
|
||||
|
||||
InputSource source = new InputSource(inStream);
|
||||
xr.parse(source);
|
||||
}
|
||||
catch (SAXException e)
|
||||
{
|
||||
System.err.println("AuthReqMsg()- Parse exception: " + e.toString());
|
||||
throw new Exception("Protocol error");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Method to get the authentication realm.
|
||||
*/
|
||||
public String getRealm() throws Exception
|
||||
{
|
||||
return m_realm;
|
||||
}
|
||||
|
||||
/*
|
||||
* Method to get the authentication mechanism token.
|
||||
*/
|
||||
public String getAuthMechToken() throws Exception
|
||||
{
|
||||
return m_authMechToken;
|
||||
}
|
||||
|
||||
/*
|
||||
* Method to get the authentication mechanism id.
|
||||
*/
|
||||
public String getMechanismId() throws Exception
|
||||
{
|
||||
return m_authMechanism;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail,
|
||||
* you may find current contact information at www.novell.com.
|
||||
*
|
||||
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
package com.novell.casa.authtoksvc;
|
||||
|
||||
/**
|
||||
* AuthRespMsg Class.
|
||||
*
|
||||
* This class deals with the message sent to the CASA Client as a
|
||||
* response to an authentication request. The format of the message is
|
||||
* as follows when the response includes a session token:
|
||||
*
|
||||
* <?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
* <auth_resp>
|
||||
* <status><description>OK</description>200</status>
|
||||
* <session_token><lifetime>lifetime value</lifetime>session token data</session_token>
|
||||
* </auth_resp>
|
||||
*
|
||||
* The format of the message is as follows when the response does not
|
||||
* include a session token.
|
||||
*
|
||||
* <?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
* <auth_resp>
|
||||
* <status><description>status description</description>status code</status>
|
||||
* </auth_resp>
|
||||
*
|
||||
* Plase note that the protocol utilizes the status codes defined
|
||||
* in the HTTP 1.1 Specification.
|
||||
*
|
||||
*/
|
||||
public class AuthRespMsg
|
||||
{
|
||||
|
||||
String m_msg;
|
||||
|
||||
/*
|
||||
* Constructor for a msg that does not include the session token.
|
||||
*/
|
||||
public AuthRespMsg (
|
||||
String statusDescription,
|
||||
String statusCode) throws Exception
|
||||
{
|
||||
// Get a StringBuffer to help us with the construction of the message
|
||||
StringBuffer sb = new StringBuffer();
|
||||
|
||||
// Start building the message
|
||||
sb.append(ProtoDefs.xmlDeclaration + "\r\n");
|
||||
sb.append("<" + ProtoDefs.authResponseElementName + ">" + "\r\n");
|
||||
sb.append("<" + ProtoDefs.statusElementName + ">"
|
||||
+ "<" + ProtoDefs.descriptionElementName + ">" + statusDescription + "</" + ProtoDefs.descriptionElementName + ">"
|
||||
+ statusCode + "</" + ProtoDefs.statusElementName + ">" + "\r\n");
|
||||
sb.append("</" + ProtoDefs.authResponseElementName + ">" + "\r\n");
|
||||
|
||||
// The message has now been built, save it.
|
||||
m_msg = sb.toString();
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor for a msg that includes the session token.
|
||||
*/
|
||||
public AuthRespMsg (
|
||||
String statusDescription,
|
||||
String statusCode,
|
||||
String sessionToken,
|
||||
String sessionTokenLifetime) throws Exception
|
||||
{
|
||||
// Get a StringBuffer to help us with the construction of the message
|
||||
StringBuffer sb = new StringBuffer();
|
||||
|
||||
// Start building the message
|
||||
sb.append(ProtoDefs.xmlDeclaration + "\r\n");
|
||||
sb.append("<" + ProtoDefs.authResponseElementName + ">" + "\r\n");
|
||||
sb.append("<" + ProtoDefs.statusElementName + ">"
|
||||
+ "<" + ProtoDefs.descriptionElementName + ">" + ProtoDefs.httpOkStatusMsg + "</" + ProtoDefs.descriptionElementName + ">"
|
||||
+ ProtoDefs.httpOkStatusCode + "</" + ProtoDefs.statusElementName + ">" + "\r\n");
|
||||
sb.append("<" + ProtoDefs.sessionTokenElementName + ">"
|
||||
+ "<" + ProtoDefs.lifetimeElementName + ">" + sessionTokenLifetime + "</" + ProtoDefs.lifetimeElementName + ">"
|
||||
+ sessionToken + "</" + ProtoDefs.sessionTokenElementName + ">" + "\r\n");
|
||||
sb.append("</" + ProtoDefs.authResponseElementName + ">" + "\r\n");
|
||||
|
||||
// The message has now been built, save it.
|
||||
m_msg = sb.toString();
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a string containing the AuthRespMsg.
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
return m_msg;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,466 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail,
|
||||
* you may find current contact information at www.novell.com.
|
||||
*
|
||||
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
package com.novell.casa.authtoksvc;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.XMLReader;
|
||||
import org.xml.sax.helpers.XMLReaderFactory;
|
||||
|
||||
|
||||
/*
|
||||
* AuthToken Class.
|
||||
*
|
||||
* This class constructs authentication tokens that clients can present
|
||||
* to services for authentication. The format of the authentication token
|
||||
* is as follows:
|
||||
*
|
||||
* <?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>
|
||||
*
|
||||
*/
|
||||
public class AuthToken
|
||||
{
|
||||
|
||||
private String m_token;
|
||||
private String m_lifetime;
|
||||
private String m_lifetimeShorter;
|
||||
private String m_identityTokenType;
|
||||
private StringBuffer m_identityToken;
|
||||
private String m_signature;
|
||||
|
||||
/*
|
||||
* Class for handling parsing events.
|
||||
*/
|
||||
private class SAXHandler extends org.xml.sax.helpers.DefaultHandler
|
||||
{
|
||||
private final static int AWAITING_ROOT_ELEMENT_START = 0;
|
||||
private final static int AWAITING_ROOT_ELEMENT_END = 1;
|
||||
private final static int AWAITING_SIGNATURE_ELEMENT_START = 2;
|
||||
private final static int AWAITING_SIGNATURE_ELEMENT_END = 3;
|
||||
private final static int AWAITING_SIGNATURE_DATA = 4;
|
||||
private final static int AWAITING_LIFETIME_ELEMENT_START = 5;
|
||||
private final static int AWAITING_LIFETIME_ELEMENT_END = 6;
|
||||
private final static int AWAITING_LIFETIME_DATA = 7;
|
||||
private final static int AWAITING_IDENT_TOKEN_ELEMENT_START = 8;
|
||||
private final static int AWAITING_IDENT_TOKEN_ELEMENT_END = 9;
|
||||
private final static int AWAITING_IDENT_TOKEN_DATA = 10;
|
||||
private final static int AWAITING_TYPE_ELEMENT_START = 11;
|
||||
private final static int AWAITING_TYPE_ELEMENT_END = 12;
|
||||
private final static int AWAITING_TYPE_DATA = 13;
|
||||
private final static int DONE_PARSING = 14;
|
||||
|
||||
private AuthToken m_AuthToken;
|
||||
private int m_state;
|
||||
|
||||
/*
|
||||
* Constructor
|
||||
*/
|
||||
public SAXHandler (AuthToken AuthToken)
|
||||
{
|
||||
super();
|
||||
|
||||
// Initialize our members
|
||||
m_AuthToken = AuthToken;
|
||||
m_state = AWAITING_ROOT_ELEMENT_START;
|
||||
}
|
||||
|
||||
/*
|
||||
* endDocument() implementation.
|
||||
*/
|
||||
public void endDocument () throws SAXException
|
||||
{
|
||||
// Verify that we obtained all of the required elements
|
||||
if (m_state != DONE_PARSING)
|
||||
{
|
||||
System.err.println("AuthToken SAXHandler.endDocument()- Missing element");
|
||||
throw new SAXException("Missing element");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* startElement() implementation.
|
||||
*/
|
||||
public void startElement (String uri, String name, String qName, org.xml.sax.Attributes atts) throws SAXException
|
||||
{
|
||||
// Proceed based on our state
|
||||
switch (m_state)
|
||||
{
|
||||
|
||||
case AWAITING_ROOT_ELEMENT_START:
|
||||
// Verify that we are processing the expected tag
|
||||
if (ProtoDefs.authTokenElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_SIGNATURE_ELEMENT_START;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("AuthToken SAXHandler.startElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_SIGNATURE_ELEMENT_START:
|
||||
// Verify that we are processing the expected tag
|
||||
if (ProtoDefs.signatureElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_SIGNATURE_DATA;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("AuthToken SAXHandler.startElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_LIFETIME_ELEMENT_START:
|
||||
// Verify that we are processing the expected tag
|
||||
if (ProtoDefs.lifetimeElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_LIFETIME_DATA;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("AuthToken SAXHandler.startElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case AWAITING_IDENT_TOKEN_ELEMENT_START:
|
||||
// Verify that we are processing the expected tag
|
||||
if (ProtoDefs.identTokenElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_TYPE_ELEMENT_START;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("AuthToken SAXHandler.startElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_TYPE_ELEMENT_START:
|
||||
// Verify that we are processing the expected tag
|
||||
if (ProtoDefs.typeElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_TYPE_DATA;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("AuthToken SAXHandler.startElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
System.err.println("AuthToken SAXHandler.startElement()- State error");
|
||||
throw new SAXException("State error");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* endElement() immplementation.
|
||||
*/
|
||||
public void endElement (String uri, String name, String qName) throws SAXException
|
||||
{
|
||||
// Proceed based on our state
|
||||
switch (m_state)
|
||||
{
|
||||
|
||||
case AWAITING_ROOT_ELEMENT_END:
|
||||
// Verify that we are processing the expected tag
|
||||
if (ProtoDefs.authTokenElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = DONE_PARSING;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("AuthToken SAXHandler.endElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_SIGNATURE_ELEMENT_END:
|
||||
// Verify that we are processing the expected tag
|
||||
if (ProtoDefs.signatureElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_LIFETIME_ELEMENT_START;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("AuthToken SAXHandler.endElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_LIFETIME_ELEMENT_END:
|
||||
// Verify that we are processing the expected tag
|
||||
if (ProtoDefs.lifetimeElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_IDENT_TOKEN_ELEMENT_START;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("AuthToken SAXHandler.endElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_TYPE_ELEMENT_END:
|
||||
// Verify that we are processing the expected tag
|
||||
if (ProtoDefs.typeElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_IDENT_TOKEN_DATA;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("AuthToken SAXHandler.endElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_IDENT_TOKEN_ELEMENT_END:
|
||||
// Verify that we are processing the expected tag
|
||||
if (ProtoDefs.identTokenElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_ROOT_ELEMENT_END;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("AuthToken SAXHandler.endElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
System.err.println("AuthToken SAXHandler.startElement()- State error");
|
||||
throw new SAXException("State error");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* character() implementation.
|
||||
*/
|
||||
public void characters (char ch[], int start, int length) throws SAXException
|
||||
{
|
||||
// Proceed based on our state
|
||||
switch (m_state)
|
||||
{
|
||||
|
||||
case AWAITING_SIGNATURE_DATA:
|
||||
// Consume the data
|
||||
m_AuthToken.m_signature = new String(ch, start, length);
|
||||
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_SIGNATURE_ELEMENT_END;
|
||||
break;
|
||||
|
||||
case AWAITING_LIFETIME_DATA:
|
||||
// Consume the data
|
||||
m_AuthToken.m_lifetime = new String(ch, start, length);
|
||||
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_LIFETIME_ELEMENT_END;
|
||||
break;
|
||||
|
||||
case AWAITING_TYPE_DATA:
|
||||
// Consume the data
|
||||
m_AuthToken.m_identityTokenType = new String(ch, start, length);
|
||||
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_TYPE_ELEMENT_END;
|
||||
break;
|
||||
|
||||
case AWAITING_IDENT_TOKEN_DATA:
|
||||
case AWAITING_IDENT_TOKEN_ELEMENT_END:
|
||||
// Consume the data
|
||||
m_AuthToken.m_identityToken.append(ch, start, length);
|
||||
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_IDENT_TOKEN_ELEMENT_END;
|
||||
break;
|
||||
|
||||
default:
|
||||
// Do nothing
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor.
|
||||
*/
|
||||
public AuthToken(String identityId,
|
||||
String realm,
|
||||
String targetService,
|
||||
String targetHost,
|
||||
SvcConfig svcConfig,
|
||||
EnabledSvcsConfig enabledSvcsConfig) throws Exception
|
||||
{
|
||||
// Get access to the authentication token configuration for this service
|
||||
AuthTokenConfig authTokenConfig = enabledSvcsConfig.getAuthTokenConfig(targetHost, targetService);
|
||||
if (authTokenConfig != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
// For now lets use the services of the only IdentityToken provider
|
||||
// that we have.
|
||||
//
|
||||
// tbd - Add code to allow for the consumption of tokens
|
||||
// from different providers.
|
||||
CasaIdentityToken identityToken = new CasaIdentityToken(enabledSvcsConfig.getIdenTokenConfig(targetHost, targetService));
|
||||
identityToken.initialize(identityId,
|
||||
realm,
|
||||
targetService,
|
||||
targetHost,
|
||||
svcConfig);
|
||||
|
||||
m_identityToken = new StringBuffer();
|
||||
m_identityToken.append(identityToken.getEncodedToken());
|
||||
m_identityTokenType = identityToken.getProviderType();
|
||||
|
||||
m_lifetime = authTokenConfig.getSetting(AuthTokenConfig.TokenLifetime);
|
||||
m_lifetimeShorter = authTokenConfig.getSetting(AuthTokenConfig.LifetimeShorter);
|
||||
|
||||
// Generate a signature
|
||||
// tbd - Over identToken, identToken type, and lifetime data.
|
||||
m_signature = "tbd";
|
||||
|
||||
// Get a StringBuffer to help us with the construction of the token
|
||||
StringBuffer sb = new StringBuffer();
|
||||
|
||||
// Start building the message
|
||||
sb.append(ProtoDefs.xmlDeclaration + "\r\n");
|
||||
sb.append("<" + ProtoDefs.authTokenElementName + ">" + "\r\n");
|
||||
sb.append("<" + ProtoDefs.signatureElementName + ">" + m_signature + "</" + ProtoDefs.signatureElementName + ">" + "\r\n");
|
||||
sb.append("<" + ProtoDefs.lifetimeElementName + ">" + m_lifetime + "</" + ProtoDefs.lifetimeElementName + ">" + "\r\n");
|
||||
sb.append("<" + ProtoDefs.identTokenElementName + ">"
|
||||
+ "<" + ProtoDefs.typeElementName + ">" + m_identityTokenType + "</" + ProtoDefs.typeElementName + ">"
|
||||
+ m_identityToken + "</" + ProtoDefs.identTokenElementName + ">" + "\r\n");
|
||||
sb.append("</" + ProtoDefs.authTokenElementName + ">" + "\r\n");
|
||||
|
||||
// Save the token
|
||||
m_token = sb.toString();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// tbd
|
||||
System.err.println("AuthToken()- Exception: " + e.toString());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Error: Missing authentication token config for " + targetService);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor given an authentication token string. The constructor
|
||||
* validates the token as part of its processing.
|
||||
*/
|
||||
public AuthToken(String token) throws Exception
|
||||
{
|
||||
// Decode the token string
|
||||
m_token = Base64Coder.decode(token);
|
||||
|
||||
// Instantiate string buffer for the identity token
|
||||
m_identityToken = new StringBuffer();
|
||||
|
||||
// Now parse the token into its elements
|
||||
try
|
||||
{
|
||||
// Parse the AuthToken
|
||||
XMLReader xr = XMLReaderFactory.createXMLReader();
|
||||
SAXHandler handler = new SAXHandler(this);
|
||||
xr.setContentHandler(handler);
|
||||
xr.setErrorHandler(handler);
|
||||
|
||||
ByteArrayInputStream inStream = new ByteArrayInputStream(m_token.getBytes());
|
||||
InputSource source = new InputSource(inStream);
|
||||
xr.parse(source);
|
||||
|
||||
// Verify the signature
|
||||
// tbd
|
||||
|
||||
// Verify that the token has not expired
|
||||
// tbd
|
||||
}
|
||||
catch (SAXException e)
|
||||
{
|
||||
System.err.println("AuthToken()- Parse exception: " + e.toString());
|
||||
throw new Exception("Protocol error");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a string containing the Base64 encode token.
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
return Base64Coder.encode(m_token);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the lifetime of the token.
|
||||
*/
|
||||
public String getLifetime()
|
||||
{
|
||||
// tbd - Convert to tokenLifetime and lifetimeShorter to ints, substractand then convert result to string
|
||||
return "60";
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the identity token.
|
||||
*/
|
||||
public String getIdentityToken()
|
||||
{
|
||||
return m_identityToken.toString();
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the identity token type.
|
||||
*/
|
||||
public String getIdentityTokenType()
|
||||
{
|
||||
return m_identityTokenType;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,298 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail,
|
||||
* you may find current contact information at www.novell.com.
|
||||
*
|
||||
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
package com.novell.casa.authtoksvc;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.XMLReader;
|
||||
import org.xml.sax.helpers.XMLReaderFactory;
|
||||
|
||||
/**
|
||||
* AuthTokenConfig Class.
|
||||
*
|
||||
* This class obtains and maintains authentication token configuration.
|
||||
*
|
||||
*/
|
||||
public class AuthTokenConfig
|
||||
{
|
||||
// Well known authentication token configuration settings
|
||||
public final static String TokenLifetime = "TokenLifetime";
|
||||
public final static String LifetimeShorter = "LifetimeShorter";
|
||||
public final static String IdentityTokenType = "IdentityTokenType";
|
||||
|
||||
// Default configuration values
|
||||
private String m_defaultTokenLifetimeValue = "3600"; // Seconds
|
||||
private String m_defaultLifetimeShorterValue = "5"; // Seconds
|
||||
private String m_defaultIdentityTokenTypeValue = "CasaIdentityToken";
|
||||
|
||||
private Map m_tokenSettingsMap;
|
||||
|
||||
/*
|
||||
* Class for handling parsing events.
|
||||
*/
|
||||
private class SAXHandler extends org.xml.sax.helpers.DefaultHandler
|
||||
{
|
||||
private final static int AWAITING_ROOT_ELEMENT_START = 0;
|
||||
private final static int AWAITING_SETTING_ELEMENT_START = 1;
|
||||
private final static int AWAITING_SETTING_ELEMENT_DATA = 2;
|
||||
private final static int AWAITING_SETTING_ELEMENT_END = 3;
|
||||
private final static int DONE_PARSING = 4;
|
||||
|
||||
private final static String m_rootElementName = "settings";
|
||||
|
||||
private Map m_keyMap;
|
||||
private int m_state;
|
||||
private String m_currentKey;
|
||||
|
||||
/*
|
||||
* Constructor
|
||||
*/
|
||||
public SAXHandler(Map keyMap)
|
||||
{
|
||||
super();
|
||||
|
||||
// Initialize our members
|
||||
m_keyMap = keyMap;
|
||||
m_state = AWAITING_ROOT_ELEMENT_START;
|
||||
}
|
||||
|
||||
/*
|
||||
* endDocument() implementation.
|
||||
*/
|
||||
public void endDocument () throws SAXException
|
||||
{
|
||||
// Verify that we are not in an invalid state
|
||||
if (m_state != DONE_PARSING)
|
||||
{
|
||||
System.err.println("AuthTokenConfig SAXHandler.endDocument()- Invalid state" + m_state);
|
||||
throw new SAXException("Invalid state at endDocument");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* startElement() implementation.
|
||||
*/
|
||||
public void startElement (String uri, String name, String qName, org.xml.sax.Attributes atts) throws SAXException
|
||||
{
|
||||
// Proceed based on our state
|
||||
switch (m_state)
|
||||
{
|
||||
case AWAITING_ROOT_ELEMENT_START:
|
||||
// Verify that we are processing the expected tag
|
||||
if (m_rootElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_SETTING_ELEMENT_START;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("AuthTokenConfig SAXHandler.startElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_SETTING_ELEMENT_START:
|
||||
// Keep track of the key name
|
||||
m_currentKey = qName;
|
||||
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_SETTING_ELEMENT_DATA;
|
||||
break;
|
||||
|
||||
default:
|
||||
System.err.println("AuthTokenConfig SAXHandler.startElement()- Invalid state " + m_state);
|
||||
throw new SAXException("Invalid state at startElement");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* endElement() immplementation.
|
||||
*/
|
||||
public void endElement (String uri, String name, String qName) throws SAXException
|
||||
{
|
||||
// Proceed based on our state
|
||||
switch (m_state)
|
||||
{
|
||||
case AWAITING_SETTING_ELEMENT_DATA:
|
||||
case AWAITING_SETTING_ELEMENT_END:
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_SETTING_ELEMENT_START;
|
||||
break;
|
||||
|
||||
case AWAITING_SETTING_ELEMENT_START:
|
||||
// Verify that we are processing the expected tag
|
||||
if (m_rootElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = DONE_PARSING;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("AuthTokenConfig SAXHandler.endElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
System.err.println("AuthTokenConfig SAXHandler.endElement()- Invalid state " + m_state);
|
||||
throw new SAXException("Invalid state at endElement");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* character() implementation.
|
||||
*/
|
||||
public void characters (char ch[], int start, int length) throws SAXException
|
||||
{
|
||||
// Consume the data if in the right state
|
||||
if (m_state == AWAITING_SETTING_ELEMENT_DATA)
|
||||
{
|
||||
// Consume the data and add the key to map
|
||||
m_keyMap.put(m_currentKey, new String(ch, start, length));
|
||||
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_SETTING_ELEMENT_END;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor which sets default configuration values.
|
||||
*/
|
||||
public AuthTokenConfig() throws Exception
|
||||
{
|
||||
System.err.println("AuthTokenConfig()- Default");
|
||||
|
||||
// Create a map to keep track of the token settings
|
||||
m_tokenSettingsMap = new HashMap();
|
||||
|
||||
// Set the default settings in our map
|
||||
m_tokenSettingsMap.put(TokenLifetime, m_defaultTokenLifetimeValue);
|
||||
m_tokenSettingsMap.put(LifetimeShorter, m_defaultLifetimeShorterValue);
|
||||
m_tokenSettingsMap.put(IdentityTokenType, m_defaultIdentityTokenTypeValue);
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor.
|
||||
*/
|
||||
public AuthTokenConfig(String authTokenSettingsFileName) throws Exception
|
||||
{
|
||||
System.err.println("AuthTokenConfig()-");
|
||||
|
||||
// Create a map to keep track of the token settings
|
||||
m_tokenSettingsMap = new HashMap();
|
||||
|
||||
try
|
||||
{
|
||||
// Get an input stream to read from the token settings file
|
||||
File f = new File(authTokenSettingsFileName);
|
||||
FileInputStream inStream = new FileInputStream(f);
|
||||
|
||||
// Parse the file
|
||||
XMLReader xr = XMLReaderFactory.createXMLReader();
|
||||
SAXHandler handler = new SAXHandler(m_tokenSettingsMap);
|
||||
xr.setContentHandler(handler);
|
||||
xr.setErrorHandler(handler);
|
||||
|
||||
InputSource source = new InputSource(inStream);
|
||||
xr.parse(source);
|
||||
|
||||
inStream.close();
|
||||
}
|
||||
catch (SAXException e)
|
||||
{
|
||||
System.err.println("AuthTokenConfig()- " + authTokenSettingsFileName + " format error, exception: " + e.toString());
|
||||
throw new Exception("AuthTokenConfig()- authtoken.settings format error");
|
||||
}
|
||||
catch (SecurityException e)
|
||||
{
|
||||
System.err.println("AuthTokenConfig()- SecurityException accessing " + authTokenSettingsFileName + " Exception=" + e.toString());
|
||||
throw new Exception("AuthTokenConfig()- Not able to access file");
|
||||
}
|
||||
catch (FileNotFoundException e)
|
||||
{
|
||||
System.err.println("AuthTokenConfig()- File " + authTokenSettingsFileName + " not found");
|
||||
throw new Exception("AuthTokenConfig()- File not found");
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
System.err.println("AuthTokenConfig()- IOException accessing " + authTokenSettingsFileName + " Exception=" + e.toString());
|
||||
throw new Exception("AuthTokenConfig()- Read error");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the value associated with the specified setting.
|
||||
*/
|
||||
public String getSetting(String settingName) throws Exception
|
||||
{
|
||||
// Try to find the setting in our map
|
||||
String value = (String) m_tokenSettingsMap.get(settingName);
|
||||
if (value == null)
|
||||
{
|
||||
System.err.println("AuthTokenConfig.getSetting()- Did not find setting " + settingName);
|
||||
|
||||
// The setting is not in our map, check if it is one to
|
||||
// which we have defaults.
|
||||
if (settingName.equals(TokenLifetime) == true)
|
||||
{
|
||||
value = m_defaultTokenLifetimeValue;
|
||||
System.err.println("AuthTokenConfig.getSetting()- Assigning default value " + value);
|
||||
|
||||
// Add the key to the map so that it can be found quicker next time
|
||||
m_tokenSettingsMap.put(TokenLifetime, m_defaultTokenLifetimeValue);
|
||||
}
|
||||
else if (settingName.equals(LifetimeShorter) == true)
|
||||
{
|
||||
value = m_defaultLifetimeShorterValue;
|
||||
System.err.println("AuthTokenConfig.getSetting()- Assigning default value " + value);
|
||||
|
||||
// Add the key to the map so that it can be found quicker next time
|
||||
m_tokenSettingsMap.put(LifetimeShorter, m_defaultLifetimeShorterValue);
|
||||
}
|
||||
else if (settingName.equals(IdentityTokenType) == true)
|
||||
{
|
||||
value = m_defaultLifetimeShorterValue;
|
||||
System.err.println("AuthTokenConfig.getSetting()- Assigning default value " + value);
|
||||
|
||||
// Add the key to the map so that it can be found quicker next time
|
||||
m_tokenSettingsMap.put(IdentityTokenType, m_defaultIdentityTokenTypeValue);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("AuthTokenConfig.getSetting()- Found setting " + settingName);
|
||||
System.err.println("AuthTokenConfig.getSetting()- Setting value = " + value);
|
||||
|
||||
// Do some sanity checking
|
||||
// tbd - Make sure that the token lifetime values are greater than the LifetimeShorter
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,341 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail,
|
||||
* you may find current contact information at www.novell.com.
|
||||
*
|
||||
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
package com.novell.casa.authtoksvc;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
import java.net.URL;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URLClassLoader;
|
||||
|
||||
/**
|
||||
* Authenticate Class.
|
||||
*
|
||||
* This class processes authentication requests.
|
||||
*
|
||||
*/
|
||||
public class Authenticate implements RpcMethod
|
||||
{
|
||||
private static final String m_mechanismSettingsFileName = "mechanism.settings";
|
||||
|
||||
private Map m_authMechanismMap;
|
||||
|
||||
private SvcConfig m_svcConfig;
|
||||
private EnabledSvcsConfig m_enabledSvcsConfig;
|
||||
|
||||
/*
|
||||
* Constructor
|
||||
*/
|
||||
public Authenticate() throws Exception
|
||||
{
|
||||
// Create a map to keep track of the authentication mechanisms
|
||||
m_authMechanismMap = new HashMap();
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the Rpc method.
|
||||
*/
|
||||
public void init(SvcConfig svcConfig, EnabledSvcsConfig enabledSvcsConfig) throws Exception
|
||||
{
|
||||
m_svcConfig = svcConfig;
|
||||
m_enabledSvcsConfig = enabledSvcsConfig;
|
||||
|
||||
// Now go through the configured authentication mechanisms, as we do so, instantiate
|
||||
// the mechanisms and place them in our map. Note that the mechanisms config folder
|
||||
// contains folders for each installed authentication mechanism. The name of these
|
||||
// folders usually match the name of the Authentication mechanisms.
|
||||
String svcConfigPath = svcConfig.getSetting(SvcConfig.ConfigFolderPath);
|
||||
File mechanismsConfigFolder = new File(svcConfigPath, "auth_mechanisms");
|
||||
try
|
||||
{
|
||||
String[] mechanismsConfigFolderObjs = mechanismsConfigFolder.list();
|
||||
if (mechanismsConfigFolderObjs != null)
|
||||
{
|
||||
for (int i = 0; i < mechanismsConfigFolderObjs.length; i++)
|
||||
{
|
||||
// Check if we are dealing with a file or a folder
|
||||
File mechanismFolder = new File(mechanismsConfigFolder, mechanismsConfigFolderObjs[i]);
|
||||
try
|
||||
{
|
||||
if (mechanismFolder.isDirectory() == true)
|
||||
{
|
||||
System.err.println("Authenticate.init()- Mechanism folder " + mechanismFolder + " is directory");
|
||||
|
||||
// Try to obtain the mechanism settings
|
||||
try
|
||||
{
|
||||
AuthMechConfig mechConfig = new AuthMechConfig(mechanismFolder + File.separator + m_mechanismSettingsFileName);
|
||||
|
||||
// Mechanism settings obtained, now instantiate it and place it in our map.
|
||||
//
|
||||
String mechClassName = mechConfig.getSetting(AuthMechConfig.ClassName);
|
||||
if (mechClassName != null)
|
||||
{
|
||||
// We now know the name of the class implementing the mechanism, now lets
|
||||
// get the relative path to the class file. Note that the path is relative
|
||||
// to the root folder of our application.
|
||||
String relativePath = mechConfig.getSetting(AuthMechConfig.RelativeClassPath);
|
||||
if (relativePath != null)
|
||||
{
|
||||
// Create a file object to the folder containing the class file. Note that we need to
|
||||
// ultimately instantiate objects from a class loaded by the same class loader that
|
||||
// loads the AuthMechanism class to avoid ClassCastExceptions.
|
||||
File mechClassPathFile = new File(svcConfig.getSetting(SvcConfig.AppRootPath) + relativePath);
|
||||
System.err.println("Authenticate.init()- Mechanism path = " + mechClassPathFile);
|
||||
try
|
||||
{
|
||||
URL methClassPathUrl = mechClassPathFile.toURL();
|
||||
URL[] urls = new URL[]{methClassPathUrl};
|
||||
|
||||
// Create a class loader for the folder
|
||||
ClassLoader customClassLoader = new URLClassLoader(urls);
|
||||
|
||||
// Load the mech class using our custom loader
|
||||
Class mechClass = customClassLoader.loadClass(mechClassName);
|
||||
FileOutputStream fos = new FileOutputStream(svcConfig.getSetting(SvcConfig.AppRootPath) + "tmp");
|
||||
ObjectOutputStream oos = new ObjectOutputStream(fos);
|
||||
oos.writeObject(mechClass);
|
||||
oos.close();
|
||||
fos.close();
|
||||
FileInputStream fis = new FileInputStream(svcConfig.getSetting(SvcConfig.AppRootPath) + "tmp");
|
||||
ObjectInputStream ois = new ObjectInputStream(fis);
|
||||
mechClass = (Class) ois.readObject();
|
||||
ois.close();
|
||||
fis.close();
|
||||
|
||||
// Now reload the class using the class loader for our AuthMechanism class
|
||||
AuthMechanism mechanism = (AuthMechanism) mechClass.newInstance();
|
||||
mechanism.init(svcConfig, mechConfig);
|
||||
m_authMechanismMap.put(mechanism.getId(), mechanism);
|
||||
}
|
||||
catch (MalformedURLException e)
|
||||
{
|
||||
System.err.println("Authenticate.init()- MalformedURLException for " + mechanismFolder + File.separator + m_mechanismSettingsFileName + " Exception=" + e.toString());
|
||||
}
|
||||
catch (ClassNotFoundException e)
|
||||
{
|
||||
System.err.println("Authenticate.init()- ClassNotFoundException for " + mechanismFolder + File.separator + m_mechanismSettingsFileName + " Exception=" + e.toString());
|
||||
}
|
||||
catch (InstantiationException e)
|
||||
{
|
||||
System.err.println("Authenticate.init()- InstantiationException for " + mechanismFolder + File.separator + m_mechanismSettingsFileName + " Exception=" + e.toString());
|
||||
}
|
||||
catch (IllegalAccessException e)
|
||||
{
|
||||
System.err.println("Authenticate.init()- IllegalAccessException for " + mechanismFolder + File.separator + m_mechanismSettingsFileName + " Exception=" + e.toString());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// A relative path was not configured, check if instead a full path was configured.
|
||||
String classPath = mechConfig.getSetting(AuthMechConfig.ClassPath);
|
||||
if (classPath != null)
|
||||
{
|
||||
// Create a file object to the folder containing the class file. Note that we need to
|
||||
// ultimately instantiate objects from a class loaded by the same class loader that
|
||||
// loads the AuthMechanism class to avoid ClassCastExceptions.
|
||||
File mechClassPathFile = new File(classPath);
|
||||
System.err.println("Authenticate.init()- Mechanism path = " + mechClassPathFile);
|
||||
try
|
||||
{
|
||||
URL methClassPathUrl = mechClassPathFile.toURL();
|
||||
URL[] urls = new URL[]{methClassPathUrl};
|
||||
|
||||
// Create a class loader for the folder
|
||||
ClassLoader customClassLoader = new URLClassLoader(urls);
|
||||
|
||||
// Load the mech class using our custom loader
|
||||
Class mechClass = customClassLoader.loadClass(mechClassName);
|
||||
FileOutputStream fos = new FileOutputStream(svcConfig.getSetting(SvcConfig.AppRootPath) + "tmp");
|
||||
ObjectOutputStream oos = new ObjectOutputStream(fos);
|
||||
oos.writeObject(mechClass);
|
||||
oos.close();
|
||||
fos.close();
|
||||
FileInputStream fis = new FileInputStream(svcConfig.getSetting(SvcConfig.AppRootPath) + "tmp");
|
||||
ObjectInputStream ois = new ObjectInputStream(fis);
|
||||
mechClass = (Class) ois.readObject();
|
||||
ois.close();
|
||||
fis.close();
|
||||
|
||||
// Now reload the class using the class loader for our AuthMechanism class
|
||||
AuthMechanism mechanism = (AuthMechanism) mechClass.newInstance();
|
||||
mechanism.init(svcConfig, mechConfig);
|
||||
m_authMechanismMap.put(mechanism.getId(), mechanism);
|
||||
}
|
||||
catch (MalformedURLException e)
|
||||
{
|
||||
System.err.println("Authenticate.init()- MalformedURLException for " + mechanismFolder + File.separator + m_mechanismSettingsFileName + " Exception=" + e.toString());
|
||||
}
|
||||
catch (ClassNotFoundException e)
|
||||
{
|
||||
System.err.println("Authenticate.init()- ClassNotFoundException for " + mechanismFolder + File.separator + m_mechanismSettingsFileName + " Exception=" + e.toString());
|
||||
}
|
||||
catch (InstantiationException e)
|
||||
{
|
||||
System.err.println("Authenticate.init()- InstantiationException for " + mechanismFolder + File.separator + m_mechanismSettingsFileName + " Exception=" + e.toString());
|
||||
}
|
||||
catch (IllegalAccessException e)
|
||||
{
|
||||
System.err.println("Authenticate.init()- IllegalAccessException for " + mechanismFolder + File.separator + m_mechanismSettingsFileName + " Exception=" + e.toString());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("Authenticate.init()- No configuration to find class path to load " + mechanismFolder + File.separator + m_mechanismSettingsFileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("Authenticate.init()- No configured mechanism class name for " + mechanismFolder + File.separator + m_mechanismSettingsFileName);
|
||||
}
|
||||
}
|
||||
catch (SecurityException e)
|
||||
{
|
||||
System.err.println("Authenticate.init()- SecurityException accessing " + mechanismFolder + File.separator + m_mechanismSettingsFileName + " Exception=" + e.toString());
|
||||
}
|
||||
catch (FileNotFoundException e)
|
||||
{
|
||||
System.err.println("Authenticate.init()- No authentication policy file for " + mechanismFolder);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
System.err.println("Authenticate.init()- IOException reading " + mechanismFolder + File.separator + m_mechanismSettingsFileName + " Exception=" + e.toString());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
System.err.println("Authenticate.init()- Exception instantiating mechConfig or mechanism " + mechanismFolder + File.separator + m_mechanismSettingsFileName + " Exception=" + e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (SecurityException e)
|
||||
{
|
||||
System.err.println("Authenticate.init()- SecurityException accessing " + mechanismFolder + " Exception=" + e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("Authenticate.init()- Unable to obtain mechanisms folder " + mechanismsConfigFolder + " objects");
|
||||
}
|
||||
}
|
||||
catch (SecurityException e)
|
||||
{
|
||||
System.err.println("Authenticate.init()- SecurityException accessing " + mechanismsConfigFolder + " Exception=" + e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Process Rpc.
|
||||
*/
|
||||
public void invoke(InputStream inStream, PrintWriter out) throws IOException
|
||||
{
|
||||
try
|
||||
{
|
||||
System.err.println("Authenticate.invoke()");
|
||||
|
||||
// Parse the AuthReqMsg sent from the client
|
||||
AuthReqMsg authReqMsg = new AuthReqMsg(inStream);
|
||||
|
||||
// Get the necessary authentication mechanism
|
||||
AuthMechanism authMechanism = (AuthMechanism) m_authMechanismMap.get(authReqMsg.getMechanismId());
|
||||
if (authMechanism != null)
|
||||
{
|
||||
// Invoke the mechanism to authenticate the entity
|
||||
String identId = authMechanism.invoke(authReqMsg);
|
||||
|
||||
// Create response based on the identity resolution results
|
||||
if (identId != null && identId.length() != 0)
|
||||
{
|
||||
System.err.println("Authenticate.invoke()- identId resolved, " + identId);
|
||||
|
||||
// An identity was resolved, get a SessionToken for it.
|
||||
SessionToken sessionToken = new SessionToken(identId,
|
||||
authReqMsg.getRealm(),
|
||||
m_svcConfig.getSetting(SvcConfig.SessionTokenLifetime));
|
||||
|
||||
// Write out the response
|
||||
AuthRespMsg authRespMsg = new AuthRespMsg(ProtoDefs.httpOkStatusMsg,
|
||||
ProtoDefs.httpOkStatusCode,
|
||||
sessionToken.toString(),
|
||||
m_svcConfig.getSetting(SvcConfig.SessionTokenLifetime));
|
||||
// tbd - Convert to ints, perform calculation, and then convert result to string
|
||||
//m_svcConfig.getSetting(SvcConfig.SessionTokenLifetime)
|
||||
//- m_svcConfig.getSetting(SvcConfig.LifetimeShorter));
|
||||
out.println(authRespMsg.toString());
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("Authenticate.invoke()- identId not resolved");
|
||||
|
||||
// Write out the response
|
||||
AuthRespMsg authRespMsg = new AuthRespMsg(ProtoDefs.httpUnauthorizedStatusMsg,
|
||||
ProtoDefs.httpUnauthorizedStatusCode);
|
||||
out.println(authRespMsg.toString());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("Authenticate.invoke()- Unsupported mechanism " + authReqMsg.getMechanismId());
|
||||
|
||||
// Write out the response
|
||||
AuthRespMsg authRespMsg = new AuthRespMsg(ProtoDefs.httpNotFoundStatusMsg,
|
||||
ProtoDefs.httpNotFoundStatusCode);
|
||||
out.println(authRespMsg.toString());
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
System.err.println("Authenticate.invoke()- Exception: " + e.toString());
|
||||
|
||||
// Write out the response
|
||||
try
|
||||
{
|
||||
AuthRespMsg authRespMsg = new AuthRespMsg(ProtoDefs.httpServerErrorStatusMsg,
|
||||
ProtoDefs.httpServerErrorStatusCode);
|
||||
out.println(authRespMsg.toString());
|
||||
}
|
||||
catch (Exception e2)
|
||||
{
|
||||
System.err.println("Authenticate.invoke()- Exception trying to construct response msg: " + e2.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the method id.
|
||||
*/
|
||||
public String getId()
|
||||
{
|
||||
return "Authenticate";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* A Base64 Encoder/Decoder.
|
||||
*
|
||||
* This class is used to encode and decode data in Base64 format
|
||||
* as described in RFC 1521.
|
||||
*
|
||||
* <p>
|
||||
* Copyright 2003: Christian d'Heureuse, Inventec Informatik AG, Switzerland.<br>
|
||||
* License: This is "Open Source" software and released under the <a href="http://www.gnu.org/licenses/lgpl.html" target="_top">GNU/LGPL</a> license.
|
||||
* It is provided "as is" without warranty of any kind. Please contact the author for other licensing arrangements.<br>
|
||||
* Home page: <a href="http://www.source-code.biz" target="_top">www.source-code.biz</a><br>
|
||||
*
|
||||
* <p>
|
||||
* Version history:<br>
|
||||
* 2003-07-22 Christian d'Heureuse (chdh): Module created.<br>
|
||||
* 2005-08-11 chdh: Lincense changed from GPL to LGPL.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
package com.novell.casa.authtoksvc;
|
||||
|
||||
public class Base64Coder {
|
||||
|
||||
// Mapping table from 6-bit nibbles to Base64 characters.
|
||||
private static char[] map1 = new char[64];
|
||||
static {
|
||||
int i=0;
|
||||
for (char c='A'; c<='Z'; c++) map1[i++] = c;
|
||||
for (char c='a'; c<='z'; c++) map1[i++] = c;
|
||||
for (char c='0'; c<='9'; c++) map1[i++] = c;
|
||||
map1[i++] = '+'; map1[i++] = '/'; }
|
||||
|
||||
// Mapping table from Base64 characters to 6-bit nibbles.
|
||||
private static byte[] map2 = new byte[128];
|
||||
static {
|
||||
for (int i=0; i<map2.length; i++) map2[i] = -1;
|
||||
for (int i=0; i<64; i++) map2[map1[i]] = (byte)i; }
|
||||
|
||||
/**
|
||||
* Encodes a string into Base64 format.
|
||||
* No blanks or line breaks are inserted.
|
||||
* @param s a String to be encoded.
|
||||
* @return A String with the Base64 encoded data.
|
||||
*/
|
||||
public static String encode (String s) {
|
||||
return new String(encode(s.getBytes())); }
|
||||
|
||||
/**
|
||||
* Encodes a byte array into Base64 format.
|
||||
* No blanks or line breaks are inserted.
|
||||
* @param in an array containing the data bytes to be encoded.
|
||||
* @return A character array with the Base64 encoded data.
|
||||
*/
|
||||
public static char[] encode (byte[] in) {
|
||||
int iLen = in.length;
|
||||
int oDataLen = (iLen*4+2)/3; // output length without padding
|
||||
int oLen = ((iLen+2)/3)*4; // output length including padding
|
||||
char[] out = new char[oLen];
|
||||
int ip = 0;
|
||||
int op = 0;
|
||||
while (ip < iLen) {
|
||||
int i0 = in[ip++] & 0xff;
|
||||
int i1 = ip < iLen ? in[ip++] & 0xff : 0;
|
||||
int i2 = ip < iLen ? in[ip++] & 0xff : 0;
|
||||
int o0 = i0 >>> 2;
|
||||
int o1 = ((i0 & 3) << 4) | (i1 >>> 4);
|
||||
int o2 = ((i1 & 0xf) << 2) | (i2 >>> 6);
|
||||
int o3 = i2 & 0x3F;
|
||||
out[op++] = map1[o0];
|
||||
out[op++] = map1[o1];
|
||||
out[op] = op < oDataLen ? map1[o2] : '='; op++;
|
||||
out[op] = op < oDataLen ? map1[o3] : '='; op++; }
|
||||
return out; }
|
||||
|
||||
/**
|
||||
* Decodes a Base64 string.
|
||||
* @param s a Base64 String to be decoded.
|
||||
* @return A String containing the decoded data.
|
||||
* @throws IllegalArgumentException if the input is not valid Base64 encoded data.
|
||||
*/
|
||||
public static String decode (String s) {
|
||||
return new String(decode(s.toCharArray())); }
|
||||
|
||||
/**
|
||||
* Decodes Base64 data.
|
||||
* No blanks or line breaks are allowed within the Base64 encoded data.
|
||||
* @param in a character array containing the Base64 encoded data.
|
||||
* @return An array containing the decoded data bytes.
|
||||
* @throws IllegalArgumentException if the input is not valid Base64 encoded data.
|
||||
*/
|
||||
public static byte[] decode (char[] in) {
|
||||
int iLen = in.length;
|
||||
if (iLen%4 != 0) throw new IllegalArgumentException ("Length of Base64 encoded input string is not a multiple of 4.");
|
||||
while (iLen > 0 && in[iLen-1] == '=') iLen--;
|
||||
int oLen = (iLen*3) / 4;
|
||||
byte[] out = new byte[oLen];
|
||||
int ip = 0;
|
||||
int op = 0;
|
||||
while (ip < iLen) {
|
||||
int i0 = in[ip++];
|
||||
int i1 = in[ip++];
|
||||
int i2 = ip < iLen ? in[ip++] : 'A';
|
||||
int i3 = ip < iLen ? in[ip++] : 'A';
|
||||
if (i0 > 127 || i1 > 127 || i2 > 127 || i3 > 127)
|
||||
throw new IllegalArgumentException ("Illegal character in Base64 encoded data.");
|
||||
int b0 = map2[i0];
|
||||
int b1 = map2[i1];
|
||||
int b2 = map2[i2];
|
||||
int b3 = map2[i3];
|
||||
if (b0 < 0 || b1 < 0 || b2 < 0 || b3 < 0)
|
||||
throw new IllegalArgumentException ("Illegal character in Base64 encoded data.");
|
||||
int o0 = ( b0 <<2) | (b1>>>4);
|
||||
int o1 = ((b1 & 0xf)<<4) | (b2>>>2);
|
||||
int o2 = ((b2 & 3)<<6) | b3;
|
||||
out[op++] = (byte)o0;
|
||||
if (op<oLen) out[op++] = (byte)o1;
|
||||
if (op<oLen) out[op++] = (byte)o2; }
|
||||
return out; }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,775 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail,
|
||||
* you may find current contact information at www.novell.com.
|
||||
*
|
||||
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
package com.novell.casa.authtoksvc;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.util.HashSet;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.naming.Context;
|
||||
import javax.naming.NamingEnumeration;
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.directory.Attributes;
|
||||
import javax.naming.directory.DirContext;
|
||||
import javax.naming.directory.InitialDirContext;
|
||||
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.XMLReader;
|
||||
import org.xml.sax.helpers.XMLReaderFactory;
|
||||
|
||||
import org.bandit.ia.IAContext;
|
||||
|
||||
/*
|
||||
* CasaIdentityToken Class.
|
||||
*
|
||||
* This class constructs Casa Identity tokens.
|
||||
*
|
||||
* A Casa Identity Token is a simple XML Document
|
||||
* with information about an identity in the form
|
||||
* of:
|
||||
*
|
||||
* <?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
* <casa_ident_tok>
|
||||
* <id>identity id</id>
|
||||
* <source_name>identity data source name</source_name>
|
||||
* <source_url>identity data source url</source_url>
|
||||
* <target_service>target service name</target_service>
|
||||
* <target_host>target host name</target_host>
|
||||
* <attributes>
|
||||
* <attribute name>attribute value</attribute name>
|
||||
* <attribute2 name>attribute2 value</attribute name>
|
||||
* ...
|
||||
* </attributes>
|
||||
* </casa_ident_tok>
|
||||
*
|
||||
*
|
||||
* attribute/values pairs. The attribute names
|
||||
* being the XML elements of the documents.
|
||||
*
|
||||
*/
|
||||
public class CasaIdentityToken implements IdentityToken
|
||||
{
|
||||
/*
|
||||
* XML Element Name Constants for the documents exchanged between the
|
||||
* Casa Client and the Casa Server.
|
||||
*/
|
||||
private final static String casaIdentTokElementName = "casa_ident_tok";
|
||||
private final static String idElementName = "id";
|
||||
private final static String sourceNameElementName = "source_name";
|
||||
private final static String sourceUrlElementName = "source_url";
|
||||
private final static String targetServiceElementName = "target_service";
|
||||
private final static String targetHostElementName = "target_host";
|
||||
private final static String attributesElementName = "attributes";
|
||||
|
||||
private IdenTokenConfig m_idenTokenConfig;
|
||||
|
||||
private String m_identityId = null;
|
||||
private String m_sourceName = null;
|
||||
private String m_sourceUrl = null;
|
||||
private String m_service = null;
|
||||
private String m_host = null;
|
||||
private String m_token = null;
|
||||
private javax.naming.directory.Attributes m_attributes = null;
|
||||
|
||||
/*
|
||||
* Class for handling Authentication Request parsing events.
|
||||
*/
|
||||
private class SAXHandler extends org.xml.sax.helpers.DefaultHandler
|
||||
{
|
||||
private final static int AWAITING_ROOT_ELEMENT_START = 0;
|
||||
private final static int AWAITING_ROOT_ELEMENT_END = 1;
|
||||
private final static int AWAITING_ID_ELEMENT_START = 2;
|
||||
private final static int AWAITING_ID_ELEMENT_END = 3;
|
||||
private final static int AWAITING_ID_DATA = 4;
|
||||
private final static int AWAITING_SOURCE_NAME_ELEMENT_START = 5;
|
||||
private final static int AWAITING_SOURCE_NAME_ELEMENT_END = 6;
|
||||
private final static int AWAITING_SOURCE_NAME_DATA = 7;
|
||||
private final static int AWAITING_SOURCE_URL_ELEMENT_START = 8;
|
||||
private final static int AWAITING_SOURCE_URL_ELEMENT_END = 9;
|
||||
private final static int AWAITING_SOURCE_URL_DATA = 10;
|
||||
private final static int AWAITING_TARGET_SERVICE_ELEMENT_START = 11;
|
||||
private final static int AWAITING_TARGET_SERVICE_ELEMENT_END = 12;
|
||||
private final static int AWAITING_TARGET_SERVICE_DATA = 13;
|
||||
private final static int AWAITING_TARGET_HOST_ELEMENT_START = 14;
|
||||
private final static int AWAITING_TARGET_HOST_ELEMENT_END = 15;
|
||||
private final static int AWAITING_TARGET_HOST_DATA = 16;
|
||||
private final static int AWAITING_ATTRIBUTES_ELEMENT_START = 17;
|
||||
private final static int AWAITING_ATTRIBUTE_START = 18;
|
||||
private final static int AWAITING_ATTRIBUTE_END = 19;
|
||||
private final static int AWAITING_ATTRIBUTE_DATA = 20;
|
||||
private final static int AWAITING_BINARY_ATTRIBUTE_DATA = 21;
|
||||
private final static int DONE_PARSING = 22;
|
||||
|
||||
private CasaIdentityToken m_casaIdentToken;
|
||||
private int m_state;
|
||||
private String m_currAttribute;
|
||||
private boolean m_encryptedAttrs;
|
||||
|
||||
/*
|
||||
* Constructor
|
||||
*/
|
||||
public SAXHandler (CasaIdentityToken casaIdentityToken)
|
||||
{
|
||||
super();
|
||||
|
||||
// Initialize our members
|
||||
m_casaIdentToken = casaIdentityToken;
|
||||
m_state = AWAITING_ROOT_ELEMENT_START;
|
||||
}
|
||||
|
||||
/*
|
||||
* endDocument() implementation.
|
||||
*/
|
||||
public void endDocument () throws SAXException
|
||||
{
|
||||
// Verify that we obtained all of the required elements
|
||||
if (m_state != DONE_PARSING)
|
||||
{
|
||||
System.err.println("CasaIdentityToken SAXHandler.endDocument()- Missing element");
|
||||
throw new SAXException("Missing element");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* startElement() implementation.
|
||||
*/
|
||||
public void startElement (String uri, String name, String qName, org.xml.sax.Attributes atts) throws SAXException
|
||||
{
|
||||
// Proceed based on our state
|
||||
switch (m_state)
|
||||
{
|
||||
|
||||
case AWAITING_ROOT_ELEMENT_START:
|
||||
// Verify that we are processing the expected tag
|
||||
if (casaIdentTokElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_ID_ELEMENT_START;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("CasaIdentityToken SAXHandler.startElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_ID_ELEMENT_START:
|
||||
// Verify that we are processing the expected tag
|
||||
if (idElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_ID_DATA;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("CasaIdentityToken SAXHandler.startElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_SOURCE_NAME_ELEMENT_START:
|
||||
// Verify that we are processing the expected tag
|
||||
if (sourceNameElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_SOURCE_NAME_DATA;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("CasaIdentityToken SAXHandler.startElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case AWAITING_SOURCE_URL_ELEMENT_START:
|
||||
// Verify that we are processing the expected tag
|
||||
if (sourceUrlElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_SOURCE_URL_DATA;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("CasaIdentityToken SAXHandler.startElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_TARGET_SERVICE_ELEMENT_START:
|
||||
// Verify that we are processing the expected tag
|
||||
if (targetServiceElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_TARGET_SERVICE_DATA;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("CasaIdentityToken SAXHandler.startElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_TARGET_HOST_ELEMENT_START:
|
||||
// Verify that we are processing the expected tag
|
||||
if (targetHostElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_TARGET_HOST_DATA;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("CasaIdentityToken SAXHandler.startElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_ATTRIBUTES_ELEMENT_START:
|
||||
// Verify that we are processing the expected tag
|
||||
if (attributesElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_ATTRIBUTE_START;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("CasaIdentityToken SAXHandler.startElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_ATTRIBUTE_START:
|
||||
// Save the element name as the current attribute
|
||||
m_currAttribute = qName;
|
||||
|
||||
// Advance to the next state based on the attribute type
|
||||
String attrType = atts.getValue("type");
|
||||
if (attrType != null && attrType.equals("binary"))
|
||||
{
|
||||
// We are dealing with a binary attribute. We are going to
|
||||
// assume that binary attributes are always base64 encoded.
|
||||
m_state = AWAITING_BINARY_ATTRIBUTE_DATA;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Assume we are dealing with an attribute of type string
|
||||
m_state = AWAITING_ATTRIBUTE_DATA;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
System.err.println("CasaIdentityToken SAXHandler.startElement()- State error");
|
||||
throw new SAXException("State error");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* endElement() immplementation.
|
||||
*/
|
||||
public void endElement (String uri, String name, String qName) throws SAXException
|
||||
{
|
||||
// Proceed based on our state
|
||||
switch (m_state)
|
||||
{
|
||||
|
||||
case AWAITING_ROOT_ELEMENT_END:
|
||||
// Verify that we are processing the expected tag
|
||||
if (casaIdentTokElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = DONE_PARSING;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("CasaIdentityToken SAXHandler.endElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_ID_ELEMENT_END:
|
||||
// Verify that we are processing the expected tag
|
||||
if (idElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_SOURCE_NAME_ELEMENT_START;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("CasaIdentityToken SAXHandler.endElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_SOURCE_NAME_ELEMENT_END:
|
||||
// Verify that we are processing the expected tag
|
||||
if (sourceNameElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_SOURCE_URL_ELEMENT_START;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("CasaIdentityToken SAXHandler.endElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_SOURCE_URL_ELEMENT_END:
|
||||
// Verify that we are processing the expected tag
|
||||
if (sourceUrlElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_TARGET_SERVICE_ELEMENT_START;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("CasaIdentityToken SAXHandler.endElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_TARGET_SERVICE_ELEMENT_END:
|
||||
// Verify that we are processing the expected tag
|
||||
if (targetServiceElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_TARGET_HOST_ELEMENT_START;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("CasaIdentityToken SAXHandler.endElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_TARGET_HOST_ELEMENT_END:
|
||||
// Verify that we are processing the expected tag
|
||||
if (targetHostElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_ATTRIBUTES_ELEMENT_START;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("CasaIdentityToken SAXHandler.endElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_ATTRIBUTE_END:
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_ATTRIBUTE_START;
|
||||
break;
|
||||
|
||||
case AWAITING_ATTRIBUTE_START:
|
||||
// Verify that we are processing the expected tag
|
||||
if (attributesElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_ROOT_ELEMENT_END;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("CasaIdentityToken SAXHandler.endElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
System.err.println("CasaIdentityToken SAXHandler.startElement()- State error");
|
||||
throw new SAXException("State error");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* character() implementation.
|
||||
*/
|
||||
public void characters (char ch[], int start, int length) throws SAXException
|
||||
{
|
||||
// Proceed based on our state
|
||||
switch (m_state)
|
||||
{
|
||||
|
||||
case AWAITING_ID_DATA:
|
||||
// Consume the data
|
||||
m_casaIdentToken.m_identityId = new String(ch, start, length);
|
||||
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_ID_ELEMENT_END;
|
||||
break;
|
||||
|
||||
case AWAITING_SOURCE_NAME_DATA:
|
||||
// Consume the data
|
||||
m_casaIdentToken.m_sourceName = new String(ch, start, length);
|
||||
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_SOURCE_NAME_ELEMENT_END;
|
||||
break;
|
||||
|
||||
case AWAITING_SOURCE_URL_DATA:
|
||||
// Consume the data
|
||||
m_casaIdentToken.m_sourceUrl = new String(ch, start, length);
|
||||
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_SOURCE_URL_ELEMENT_END;
|
||||
break;
|
||||
|
||||
case AWAITING_TARGET_SERVICE_DATA:
|
||||
// Consume the data
|
||||
m_casaIdentToken.m_service = new String(ch, start, length);
|
||||
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_TARGET_SERVICE_ELEMENT_END;
|
||||
break;
|
||||
|
||||
case AWAITING_TARGET_HOST_DATA:
|
||||
// Consume the data
|
||||
m_casaIdentToken.m_host = new String(ch, start, length);
|
||||
|
||||
// At this point we now have the target service and host names,
|
||||
// check if our configuration says that the attributes have been
|
||||
// encrypted.
|
||||
// tbd - Need to come up with a solution for obtaining configuration
|
||||
// information when instanstiated using a stream. May be the token should
|
||||
// carry an indication that the attributes are encrypted.
|
||||
m_encryptedAttrs = false;
|
||||
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_TARGET_HOST_ELEMENT_END;
|
||||
break;
|
||||
|
||||
case AWAITING_ATTRIBUTE_DATA:
|
||||
// Consume the data
|
||||
//
|
||||
// Decrypt the attribute data if necessary
|
||||
if (m_encryptedAttrs)
|
||||
{
|
||||
// tbd - Decrypt the attribute key and value with the private key of the service
|
||||
// using the configured mechanism.
|
||||
}
|
||||
else
|
||||
{
|
||||
m_casaIdentToken.m_attributes.put(m_currAttribute, new String(ch, start, length));
|
||||
}
|
||||
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_ATTRIBUTE_END;
|
||||
break;
|
||||
|
||||
case AWAITING_BINARY_ATTRIBUTE_DATA:
|
||||
// Consume the data
|
||||
//
|
||||
// Decrypt the attribute data if necessary
|
||||
if (m_encryptedAttrs)
|
||||
{
|
||||
// tbd - Decrypt the attribute key and value with the private key of the service
|
||||
// using the configured mechanism.
|
||||
}
|
||||
else
|
||||
{
|
||||
// The data is base64 encoded
|
||||
char[] encodedChars = new char[length];
|
||||
System.arraycopy(ch, start, encodedChars, 0, length);
|
||||
m_casaIdentToken.m_attributes.put(m_currAttribute, Base64Coder.decode(encodedChars));
|
||||
}
|
||||
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_ATTRIBUTE_END;
|
||||
break;
|
||||
|
||||
default:
|
||||
// Do nothing
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor.
|
||||
*/
|
||||
public CasaIdentityToken (IdenTokenConfig idenTokenConfig)
|
||||
{
|
||||
// Initialize our members
|
||||
m_token = null;
|
||||
m_attributes = new javax.naming.directory.BasicAttributes();
|
||||
m_idenTokenConfig = idenTokenConfig;
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor.
|
||||
*/
|
||||
public CasaIdentityToken ()
|
||||
{
|
||||
// Initialize our members
|
||||
m_token = null;
|
||||
m_attributes = new javax.naming.directory.BasicAttributes();
|
||||
m_idenTokenConfig = null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize with parameters.
|
||||
*/
|
||||
public void initialize (String identityId,
|
||||
String sourceName,
|
||||
String targetService,
|
||||
String targetHost,
|
||||
SvcConfig svcConfig) throws Exception
|
||||
{
|
||||
// Save input parameters
|
||||
m_identityId = identityId;
|
||||
m_sourceName = sourceName;
|
||||
m_sourceUrl = "ldap://myldaphost.novell.com:389"; // tbd - Obtain from Identity Abstraction layer
|
||||
m_service = targetService;
|
||||
m_host = targetHost;
|
||||
|
||||
try
|
||||
{
|
||||
// Open a directory context and use it to read the identity attributes.
|
||||
Hashtable env = new Hashtable();
|
||||
env.put(Context.INITIAL_CONTEXT_FACTORY, "org.bandit.ia.IAInitialCtxFactory");
|
||||
env.put(IAContext.IA_REALM_CONFIG_LOCATION, svcConfig.getSetting(SvcConfig.IdentityAbstractionConfigFile));
|
||||
env.put("java.naming.ldap.attributes.binary", "guid");
|
||||
env.put(IAContext.IA_REALM_SELECTOR, sourceName);
|
||||
|
||||
DirContext ctx = new InitialDirContext(env);
|
||||
|
||||
// Setup a string buffer for building the IdentityToken, notice for now
|
||||
// we are not going to wrap the identity token.
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append(ProtoDefs.xmlDeclaration + "\r\n");
|
||||
sb.append("<" + casaIdentTokElementName + ">" + "\r\n");
|
||||
sb.append("<" + idElementName + ">" + identityId + "</" + idElementName + ">\r\n");
|
||||
sb.append("<" + sourceNameElementName + ">" + sourceName + "</" + sourceNameElementName + ">\r\n");
|
||||
sb.append("<" + sourceUrlElementName + ">" + m_sourceUrl + "</" + sourceUrlElementName + ">\r\n");
|
||||
sb.append("<" + targetServiceElementName + ">" + m_service + "</" + targetServiceElementName + ">\r\n");
|
||||
sb.append("<" + targetHostElementName + ">" + m_host + "</" + targetHostElementName + ">\r\n");
|
||||
sb.append("<" + attributesElementName + ">" + "\r\n");
|
||||
|
||||
// Get the necessary attributes of the specified services in the identity token
|
||||
String[] attributesNeeded = m_idenTokenConfig.getAttributes();
|
||||
boolean encryptAttributes = "true".equals(m_idenTokenConfig.getSetting(IdenTokenConfig.EncryptAttributes));
|
||||
Attributes attrs = ctx.getAttributes(identityId, attributesNeeded);
|
||||
|
||||
// Now append the attributes to the token
|
||||
for (NamingEnumeration ae = attrs.getAll(); ae.hasMore();)
|
||||
{
|
||||
javax.naming.directory.Attribute attr = (javax.naming.directory.Attribute) ae.next();
|
||||
|
||||
NamingEnumeration enumeration = attr.getAll();
|
||||
while (enumeration.hasMore())
|
||||
{
|
||||
Object attrValue = enumeration.next();
|
||||
m_attributes.put(attr.getID(), attrValue);
|
||||
System.err.println("CasaIdentityToken.initialize()- Including attribute " + attr.getID());
|
||||
|
||||
// Encrypt the attribute if necessary
|
||||
if (encryptAttributes == true)
|
||||
{
|
||||
// tbd - Encrypt the attributes using the services public key, let the mechanism
|
||||
// be configurable. The service's certificate should be Base64 encoded as a setting
|
||||
// of the identoken.settings file.
|
||||
}
|
||||
else
|
||||
{
|
||||
// Proceed based on the attribute value type
|
||||
if (attrValue instanceof byte[])
|
||||
{
|
||||
// The attribute value is of type byte[], we need to encode it.
|
||||
sb.append("<" + attr.getID() + " type=\"binary\" encoding=\"base64\">" + new String(Base64Coder.encode((byte[]) attrValue)) + "</" + attr.getID() + ">" + "\r\n");
|
||||
System.err.println("Attribute " + attr.getID() + "included as " + new String(Base64Coder.encode((byte[]) attrValue)));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Assume the attribute value is of type String
|
||||
sb.append("<" + attr.getID() + ">" + (String) attrValue + "</" + attr.getID() + ">" + "\r\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
sb.append("</" + attributesElementName + ">" + "\r\n");
|
||||
sb.append("</" + casaIdentTokElementName + ">" + "\r\n");
|
||||
|
||||
m_token = sb.toString();
|
||||
}
|
||||
catch (NamingException e)
|
||||
{
|
||||
// tbd - Log the event???
|
||||
System.err.println("CasaIdentityToken.initialize()- Exception: " + e.getExplanation());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// tbd
|
||||
System.err.println("CasaIdentityToken.initialize()- Exception: " + e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the token object with an ecoded token string.
|
||||
*/
|
||||
public void initialize (String encodedToken) throws Exception
|
||||
{
|
||||
// Save copy of the token
|
||||
m_token = Base64Coder.decode(encodedToken);
|
||||
|
||||
// Now parse the token into its elements
|
||||
try
|
||||
{
|
||||
// Parse the AuthReqMsg
|
||||
XMLReader xr = XMLReaderFactory.createXMLReader();
|
||||
SAXHandler handler = new SAXHandler(this);
|
||||
xr.setContentHandler(handler);
|
||||
xr.setErrorHandler(handler);
|
||||
|
||||
|
||||
ByteArrayInputStream inStream = new ByteArrayInputStream(m_token.getBytes());
|
||||
InputSource source = new InputSource(inStream);
|
||||
xr.parse(source);
|
||||
}
|
||||
catch (SAXException e)
|
||||
{
|
||||
// tbd - Log this.
|
||||
System.err.println("CasaIdentityToken()- Parse exception: " + e.toString());
|
||||
throw new Exception("Token error");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns encoded token string.
|
||||
*
|
||||
* IMPORTANT: The token string can not contain the substring "]]>"
|
||||
* within it.
|
||||
*/
|
||||
public String getEncodedToken () throws Exception
|
||||
{
|
||||
if (m_token != null)
|
||||
{
|
||||
return Base64Coder.encode(m_token);
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("CasaIdentityToken.toString()- Not initialized");
|
||||
throw new Exception("Not initialized");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a string containing our type of identity token provider.
|
||||
*/
|
||||
public String getProviderType () throws Exception
|
||||
{
|
||||
// tbd - Change to a GUID
|
||||
return "CasaIdentityToken";
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a string containing the identity id.
|
||||
*/
|
||||
public String getIdentityId () throws Exception
|
||||
{
|
||||
if (m_identityId != null)
|
||||
return m_identityId;
|
||||
else
|
||||
{
|
||||
System.err.println("CasaIdentityToken.getIdentityId()- Not initialized");
|
||||
throw new Exception("Not initialized");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a string containing the name associated with the
|
||||
* identity source.
|
||||
*/
|
||||
public String getSourceName () throws Exception
|
||||
{
|
||||
if (m_sourceName != null)
|
||||
return m_sourceName;
|
||||
else
|
||||
{
|
||||
System.err.println("CasaIdentityToken.getSourceName()- Not initialized");
|
||||
throw new Exception("Not initialized");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a string containing the url associated with the
|
||||
* identity source.
|
||||
*/
|
||||
public String getSourceUrl () throws Exception
|
||||
{
|
||||
if (m_sourceUrl != null)
|
||||
return m_sourceUrl;
|
||||
else
|
||||
{
|
||||
System.err.println("CasaIdentityToken.getSourceUrl()- Not initialized");
|
||||
throw new Exception("Not initialized");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a string containing the name of the targeted service.
|
||||
*/
|
||||
public String getTargetService () throws Exception
|
||||
{
|
||||
if (m_service != null)
|
||||
return m_service;
|
||||
else
|
||||
{
|
||||
System.err.println("CasaIdentityToken.getTargetService()- Not initialized");
|
||||
throw new Exception("Not initialized");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a string containig the name of the host where the
|
||||
* targeted service resides.
|
||||
*/
|
||||
public String getTargetHost () throws Exception
|
||||
{
|
||||
if (m_host != null)
|
||||
return m_host;
|
||||
else
|
||||
{
|
||||
System.err.println("CasaIdentityToken.getTargetHost()- Not initialized");
|
||||
throw new Exception("Not initialized");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the attributes of the identity.
|
||||
*/
|
||||
public javax.naming.directory.Attributes getAttributes () throws Exception
|
||||
{
|
||||
if (m_attributes != null)
|
||||
return m_attributes;
|
||||
else
|
||||
{
|
||||
System.err.println("CasaIdentityToken.getIdentityAttributes()- Not initialized");
|
||||
throw new Exception("Not initialized");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,388 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail,
|
||||
* you may find current contact information at www.novell.com.
|
||||
*
|
||||
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
package com.novell.casa.authtoksvc;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* EnabledSvcsConfig Class.
|
||||
*
|
||||
* This class obtains and maintains configuration and policy information about
|
||||
* the services enabled to use Authentication Tokens.
|
||||
*
|
||||
*/
|
||||
public class EnabledSvcsConfig
|
||||
{
|
||||
private static final String m_authPolicyFileName = "auth.policy";
|
||||
private static final String m_authTokenSettingsFileName = "authtoken.settings";
|
||||
private static final String m_idenTokenSettingsFileName = "identoken.settings";
|
||||
|
||||
private Map m_hostsMap;
|
||||
|
||||
/**
|
||||
* SvcConfigEntry Class.
|
||||
*
|
||||
* This class is used to maintain the configuration and policy associated with an
|
||||
* enabled service.
|
||||
*
|
||||
*/
|
||||
private class SvcConfigEntry
|
||||
{
|
||||
protected byte[] m_authPolicyFileData;
|
||||
protected AuthTokenConfig m_authTokenConfig;
|
||||
protected IdenTokenConfig m_idenTokenConfig;
|
||||
|
||||
/*
|
||||
* Constructor.
|
||||
*/
|
||||
public SvcConfigEntry(byte[] authPolicyFileData,
|
||||
AuthTokenConfig authTokenConfig,
|
||||
IdenTokenConfig idenTokenConfig)
|
||||
{
|
||||
m_authPolicyFileData = authPolicyFileData;
|
||||
m_authTokenConfig = authTokenConfig;
|
||||
m_idenTokenConfig = idenTokenConfig;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor.
|
||||
*/
|
||||
public EnabledSvcsConfig(String svcConfigPath) throws Exception
|
||||
{
|
||||
System.err.println("EnabledSvcsConfig()-");
|
||||
System.err.println("EnabledSvcsConfig()- SvcConfigPath = " + svcConfigPath);
|
||||
|
||||
// Initialize the default auth policy, authtoken, and identtoken configs.
|
||||
byte[] defaultAuthPolicyData = null;
|
||||
AuthTokenConfig defaultAuthTokenConfig = null;
|
||||
IdenTokenConfig defaultIdenTokenConfig = null;
|
||||
|
||||
// Create a map to keep track of the enabled services and their configuration
|
||||
// for each configured host.
|
||||
m_hostsMap = new HashMap();
|
||||
|
||||
// Get access to the configuration folder for the service
|
||||
File configFolder = new File(svcConfigPath);
|
||||
try
|
||||
{
|
||||
// Try to obtain the default authentication policy
|
||||
try
|
||||
{
|
||||
File f = new File(configFolder, m_authPolicyFileName);
|
||||
defaultAuthPolicyData = new byte[(int) f.length()];
|
||||
FileInputStream inStream = new FileInputStream(f);
|
||||
int bytesRead = inStream.read(defaultAuthPolicyData);
|
||||
inStream.close();
|
||||
if (bytesRead != defaultAuthPolicyData.length)
|
||||
{
|
||||
System.err.println("EnabledSvcsConfig()- Error reading default policy file");
|
||||
}
|
||||
}
|
||||
catch (SecurityException e)
|
||||
{
|
||||
System.err.println("EnabledSvcsConfig()- SecurityException accessing " + configFolder + File.separator + m_authPolicyFileName + " Exception=" + e.toString());
|
||||
}
|
||||
catch (FileNotFoundException e)
|
||||
{
|
||||
System.err.println("EnabledSvcsConfig()- File " + configFolder + File.separator + m_authPolicyFileName + " not found");
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
System.err.println("EnabledSvcsConfig()- IOException reading " + configFolder + File.separator + m_authPolicyFileName + " Exception=" + e.toString());
|
||||
}
|
||||
|
||||
// Try to obtain the default authentication token settings
|
||||
try
|
||||
{
|
||||
defaultAuthTokenConfig = new AuthTokenConfig(configFolder + File.separator + m_authTokenSettingsFileName);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// Not able to create authentication token configuration using the default
|
||||
// file. Create one using default parameters.
|
||||
defaultAuthTokenConfig = new AuthTokenConfig();
|
||||
}
|
||||
|
||||
// Try to obtain the default identity token settings
|
||||
try
|
||||
{
|
||||
defaultIdenTokenConfig = new IdenTokenConfig(configFolder + File.separator + m_idenTokenSettingsFileName);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// Not able to create identity token configuration using the default
|
||||
// file. Create one using default parameters.
|
||||
defaultIdenTokenConfig = new IdenTokenConfig();
|
||||
}
|
||||
|
||||
// Now go through the configured hosts. Note that the services config folder
|
||||
// contains folders for each host for which there are enabled services. The folders
|
||||
// in the services config folder must match the DNS name of the hosts where
|
||||
// the enabled services reside.
|
||||
File servicesConfigFolder = new File(svcConfigPath, "enabled_services");
|
||||
try
|
||||
{
|
||||
String[] servicesConfigFolderObjs = servicesConfigFolder.list();
|
||||
if (servicesConfigFolderObjs != null)
|
||||
{
|
||||
for (int i = 0; i < servicesConfigFolderObjs.length; i++)
|
||||
{
|
||||
// Check if we are dealing with a file or a folder
|
||||
File hostFolder = new File(servicesConfigFolder, servicesConfigFolderObjs[i]);
|
||||
try
|
||||
{
|
||||
if (hostFolder.isDirectory() == true)
|
||||
{
|
||||
System.err.println("EnabledSvcsConfig()- Host folder " + hostFolder + " is directory");
|
||||
|
||||
// Now go through the services configured for this host
|
||||
String[] hostFolderObjs = hostFolder.list();
|
||||
if (hostFolderObjs != null)
|
||||
{
|
||||
// Create a Map object to hold the service configurations for this host
|
||||
Map enabledSvcsConfigMap = new HashMap();
|
||||
|
||||
for (int ii = 0; ii < hostFolderObjs.length; ii++)
|
||||
{
|
||||
// Check if we are dealing with a file or a folder
|
||||
File serviceFolder = new File(hostFolder, hostFolderObjs[ii]);
|
||||
System.err.println("EnabledSvcsConfig()- Service folder " + serviceFolder);
|
||||
try
|
||||
{
|
||||
if (serviceFolder.isDirectory() == true)
|
||||
{
|
||||
System.err.println("EnabledSvcsConfig()- Service folder " + serviceFolder + " is directory");
|
||||
|
||||
// We are dealing with a folder, remember that the folder name matches the name
|
||||
// of the enabled service. Check and see if there are authentication policy and
|
||||
// authtoken and identoken setting files configured for it.
|
||||
byte[] authPolicyData = null;
|
||||
AuthTokenConfig authTokenConfig = null;
|
||||
IdenTokenConfig idenTokenConfig = null;
|
||||
|
||||
try
|
||||
{
|
||||
File policyFile = new File(serviceFolder, m_authPolicyFileName);
|
||||
authPolicyData = new byte[(int) policyFile.length()];
|
||||
FileInputStream inStream = new FileInputStream(policyFile);
|
||||
int bytesRead = inStream.read(authPolicyData);
|
||||
inStream.close();
|
||||
if (bytesRead != authPolicyData.length)
|
||||
{
|
||||
System.err.println("EnabledSvcsConfig()- Error reading policy file for " + servicesConfigFolderObjs[i] + " " + hostFolderObjs[ii]);
|
||||
}
|
||||
}
|
||||
catch (SecurityException e)
|
||||
{
|
||||
System.err.println("EnabledSvcsConfig()- SecurityException accessing " + serviceFolder + File.separator + m_authPolicyFileName + " Exception=" + e.toString());
|
||||
}
|
||||
catch (FileNotFoundException e)
|
||||
{
|
||||
System.err.println("EnabledSvcsConfig()- No authentication policy file for " + serviceFolder);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
System.err.println("EnabledSvcsConfig()- IOException reading " + serviceFolder + File.separator + m_authPolicyFileName + " Exception=" + e.toString());
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
authTokenConfig = new AuthTokenConfig(serviceFolder + File.separator + m_authTokenSettingsFileName);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
System.err.println("EnabledSvcsConfig()- Exception accessing " + serviceFolder + File.separator + m_authTokenSettingsFileName + " Exception=" + e.toString());
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
idenTokenConfig = new IdenTokenConfig(serviceFolder + File.separator + m_idenTokenSettingsFileName);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
System.err.println("EnabledSvcsConfig()- Exception accessing " + serviceFolder + File.separator + m_idenTokenSettingsFileName + " Exception=" + e.toString());
|
||||
}
|
||||
|
||||
// Make sure that we have a policy file
|
||||
if ((authPolicyData != null && authPolicyData.length != 0)
|
||||
|| (defaultAuthPolicyData != null && defaultAuthPolicyData.length != 0))
|
||||
{
|
||||
// Instantiate SvcConfigEntry for this service and place it in our map
|
||||
SvcConfigEntry svcConfigEntry = new SvcConfigEntry((authPolicyData != null && authPolicyData.length != 0) ? authPolicyData : defaultAuthPolicyData,
|
||||
(authTokenConfig != null) ? authTokenConfig : defaultAuthTokenConfig,
|
||||
(idenTokenConfig != null) ? idenTokenConfig : defaultIdenTokenConfig);
|
||||
|
||||
// Add this entry to our map
|
||||
System.err.println("EnabledSvcsConfig()- Adding entry in map for " + servicesConfigFolderObjs[i] + " " + hostFolderObjs[ii]);
|
||||
enabledSvcsConfigMap.put(hostFolderObjs[ii], svcConfigEntry);
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("EnabledSvcsConfig()- Unable to enable " + servicesConfigFolderObjs[i] + " " + hostFolderObjs[ii] + " due to no configured authentication policy");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (SecurityException e)
|
||||
{
|
||||
System.err.println("EnabledSvcsConfig()- SecurityException accessing " + serviceFolder + " Exception=" + e.toString());
|
||||
}
|
||||
|
||||
// Add this hosts enabled services configuration map to the hosts map
|
||||
m_hostsMap.put(servicesConfigFolderObjs[i], enabledSvcsConfigMap);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("EnabledSvcsConfig()- No services configured for " + hostFolder);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (SecurityException e)
|
||||
{
|
||||
System.err.println("EnabledSvcsConfig()- SecurityException accessing " + hostFolder + " Exception=" + e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("EnabledSvcsConfig()- Unable to obtain services folder " + servicesConfigFolder + " objects");
|
||||
}
|
||||
}
|
||||
catch (SecurityException e)
|
||||
{
|
||||
System.err.println("EnabledSvcsConfig()- SecurityException accessing " + servicesConfigFolder + " Exception=" + e.toString());
|
||||
}
|
||||
}
|
||||
catch (SecurityException e)
|
||||
{
|
||||
System.err.println("EnabledSvcsConfig()- SecurityException accessing " + configFolder + " Exception=" + e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns true if the specified service has been enabled to use authentication
|
||||
* tokens.
|
||||
*/
|
||||
public boolean svcEnabled(String hostName, String serviceName)
|
||||
{
|
||||
// First try to obtain the Map of enabled services for the host
|
||||
// tbd - Should we make this case insensitive?
|
||||
Map enabledSvcsConfigMap = (Map) m_hostsMap.get(hostName);
|
||||
if (enabledSvcsConfigMap != null)
|
||||
{
|
||||
return enabledSvcsConfigMap.containsKey(serviceName);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the data associated with the authentication policy file
|
||||
* associated with the specified service.
|
||||
*/
|
||||
public byte[] getAuthPolicyFileDataForSvc(String hostName, String serviceName)
|
||||
{
|
||||
// First try to obtain the Map of enabled services for the host
|
||||
// tbd - Should we make this case insensitive?
|
||||
Map enabledSvcsConfigMap = (Map) m_hostsMap.get(hostName);
|
||||
if (enabledSvcsConfigMap != null)
|
||||
{
|
||||
// Retrieve SvcConfigEntry for the service from the map for the host
|
||||
SvcConfigEntry svcConfigEntry = (SvcConfigEntry) enabledSvcsConfigMap.get(serviceName);
|
||||
if (svcConfigEntry != null)
|
||||
{
|
||||
return svcConfigEntry.m_authPolicyFileData;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the authentication token configuration associated with the
|
||||
* specified service.
|
||||
*/
|
||||
public AuthTokenConfig getAuthTokenConfig(String hostName, String serviceName)
|
||||
{
|
||||
// First try to obtain the Map of enabled services for the host
|
||||
// tbd - Should we make this case insensitive?
|
||||
Map enabledSvcsConfigMap = (Map) m_hostsMap.get(hostName);
|
||||
if (enabledSvcsConfigMap != null)
|
||||
{
|
||||
// Retrieve SvcConfigEntry for the service from the map for the host
|
||||
SvcConfigEntry svcConfigEntry = (SvcConfigEntry) enabledSvcsConfigMap.get(serviceName);
|
||||
if (svcConfigEntry != null)
|
||||
{
|
||||
return svcConfigEntry.m_authTokenConfig;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the identity token configuration associated with the
|
||||
* specified service.
|
||||
*/
|
||||
public IdenTokenConfig getIdenTokenConfig(String hostName, String serviceName)
|
||||
{
|
||||
// First try to obtain the Map of enabled services for the host
|
||||
// tbd - Should we make this case insensitive?
|
||||
Map enabledSvcsConfigMap = (Map) m_hostsMap.get(hostName);
|
||||
if (enabledSvcsConfigMap != null)
|
||||
{
|
||||
// Retrieve SvcConfigEntry for the service from the map for the host
|
||||
SvcConfigEntry svcConfigEntry = (SvcConfigEntry) enabledSvcsConfigMap.get(serviceName);
|
||||
if (svcConfigEntry != null)
|
||||
{
|
||||
return svcConfigEntry.m_idenTokenConfig;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail,
|
||||
* you may find current contact information at www.novell.com.
|
||||
*
|
||||
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
package com.novell.casa.authtoksvc;
|
||||
|
||||
import java.io.*;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* GetAuthPolicy Class.
|
||||
*
|
||||
* This class processes get authentication policy requests for a particular
|
||||
* service.
|
||||
*
|
||||
*/
|
||||
public class GetAuthPolicy implements RpcMethod
|
||||
{
|
||||
private SvcConfig m_svcConfig;
|
||||
private EnabledSvcsConfig m_enabledSvcsConfig;
|
||||
|
||||
/*
|
||||
* Constructor.
|
||||
*/
|
||||
public GetAuthPolicy() throws Exception
|
||||
{
|
||||
// Nothing to do at this time
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the Rpc method.
|
||||
*/
|
||||
public void init(SvcConfig svcConfig, EnabledSvcsConfig enabledSvcsConfig) throws Exception
|
||||
{
|
||||
m_svcConfig = svcConfig;
|
||||
m_enabledSvcsConfig = enabledSvcsConfig;
|
||||
}
|
||||
|
||||
/*
|
||||
* Process Rpc.
|
||||
*/
|
||||
public void invoke(InputStream inStream, PrintWriter out) throws IOException
|
||||
{
|
||||
try
|
||||
{
|
||||
System.err.println("GetAuthPolicy.invoke()");
|
||||
|
||||
// Read and parse the GetAuthPolicyReqMsg sent from the client
|
||||
GetAuthPolicyReqMsg getAuthPolicyReqMsg = new GetAuthPolicyReqMsg(inStream);
|
||||
|
||||
// Verify that the service is enabled
|
||||
if (m_enabledSvcsConfig.svcEnabled(getAuthPolicyReqMsg.getHostName(), getAuthPolicyReqMsg.getServiceName()))
|
||||
{
|
||||
// Get the auth policy for the service
|
||||
byte[] authPolicy = m_enabledSvcsConfig.getAuthPolicyFileDataForSvc(getAuthPolicyReqMsg.getHostName(),
|
||||
getAuthPolicyReqMsg.getServiceName());
|
||||
if (authPolicy != null)
|
||||
{
|
||||
// Write out the response
|
||||
GetAuthPolicyRespMsg getAuthPolicyRespMsg = new GetAuthPolicyRespMsg(ProtoDefs.httpOkStatusMsg,
|
||||
ProtoDefs.httpOkStatusCode,
|
||||
new String(Base64Coder.encode(authPolicy)));
|
||||
out.println(getAuthPolicyRespMsg.toString());
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("GetAuthPolicy.invoke()- authPolicy is null for enabled service: " + getAuthPolicyReqMsg.getServiceName());
|
||||
GetAuthPolicyRespMsg getAuthPolicyRespMsg = new GetAuthPolicyRespMsg(ProtoDefs.httpServerErrorStatusMsg,
|
||||
ProtoDefs.httpServerErrorStatusCode);
|
||||
out.println(getAuthPolicyRespMsg.toString());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// The service has not been enabled to utilize our authentication tokens
|
||||
GetAuthPolicyRespMsg getAuthPolicyRespMsg = new GetAuthPolicyRespMsg(ProtoDefs.httpNotFoundStatusMsg,
|
||||
ProtoDefs.httpNotFoundStatusCode);
|
||||
out.println(getAuthPolicyRespMsg.toString());
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
System.err.println("GetAuthPolicy.invoke()- Exception: " + e.toString());
|
||||
|
||||
// Write out the response
|
||||
try
|
||||
{
|
||||
GetAuthPolicyRespMsg getAuthPolicyRespMsg = new GetAuthPolicyRespMsg(ProtoDefs.httpServerErrorStatusMsg,
|
||||
ProtoDefs.httpServerErrorStatusCode);
|
||||
out.println(getAuthPolicyRespMsg.toString());
|
||||
}
|
||||
catch (Exception e2)
|
||||
{
|
||||
System.err.println("GetAuthPolicy.invoke()- Exception trying to construct response msg: " + e2.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the method id.
|
||||
*/
|
||||
public String getId()
|
||||
{
|
||||
return "GetAuthPolicy";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,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>
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
package com.novell.casa.authtoksvc;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.XMLReader;
|
||||
import org.xml.sax.helpers.XMLReaderFactory;
|
||||
|
||||
/**
|
||||
* GetAuthPolicyReqMsg Class.
|
||||
*
|
||||
* This class deals with the message sent by Casa Client when requesting
|
||||
* authenication policy to authenticate an entity to a particular service.
|
||||
* The format of the the message is as follows:
|
||||
*
|
||||
* <?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
* <get_auth_policy_req>
|
||||
* <service>service name</service>
|
||||
* <host>host name</host>
|
||||
* </get_auth_policy_req>
|
||||
*
|
||||
*/
|
||||
public class GetAuthPolicyReqMsg
|
||||
{
|
||||
|
||||
protected String m_serviceName = null;
|
||||
protected String m_hostName = null;
|
||||
|
||||
/*
|
||||
* Class for handling GetAuthPolicyReq msg parsing events.
|
||||
*/
|
||||
private class SAXHandler extends org.xml.sax.helpers.DefaultHandler
|
||||
{
|
||||
private final static int AWAITING_ROOT_ELEMENT_START = 0;
|
||||
private final static int AWAITING_ROOT_ELEMENT_END = 1;
|
||||
private final static int AWAITING_SERVICE_ELEMENT_START = 2;
|
||||
private final static int AWAITING_SERVICE_ELEMENT_END = 3;
|
||||
private final static int AWAITING_SERVICE_DATA = 4;
|
||||
private final static int AWAITING_HOST_ELEMENT_START = 5;
|
||||
private final static int AWAITING_HOST_ELEMENT_END = 6;
|
||||
private final static int AWAITING_HOST_DATA = 7;
|
||||
private final static int DONE_PARSING = 8;
|
||||
|
||||
private GetAuthPolicyReqMsg m_GetAuthPolicyReqMsg;
|
||||
private int m_state;
|
||||
|
||||
/*
|
||||
* Constructor
|
||||
*/
|
||||
public SAXHandler (GetAuthPolicyReqMsg GetAuthPolicyReqMsg)
|
||||
{
|
||||
super();
|
||||
|
||||
// Initialize our members
|
||||
m_GetAuthPolicyReqMsg = GetAuthPolicyReqMsg;
|
||||
m_state = AWAITING_ROOT_ELEMENT_START;
|
||||
}
|
||||
|
||||
/*
|
||||
* endDocument() implementation.
|
||||
*/
|
||||
public void endDocument () throws SAXException
|
||||
{
|
||||
// Verify that we obtained all of the required elements
|
||||
if (m_state != DONE_PARSING)
|
||||
{
|
||||
System.err.println("GetAuthPolicyReqMsg SAXHandler.endDocument()- Missing element");
|
||||
throw new SAXException("Missing element");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* startElement() implementation.
|
||||
*/
|
||||
public void startElement (String uri, String name, String qName, org.xml.sax.Attributes atts) throws SAXException
|
||||
{
|
||||
// Proceed based on our state
|
||||
switch (m_state)
|
||||
{
|
||||
|
||||
case AWAITING_ROOT_ELEMENT_START:
|
||||
// Verify that we are processing the expected tag
|
||||
if (ProtoDefs.getAuthPolicyRequestElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_SERVICE_ELEMENT_START;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("GetAuthPolicyReqMsg SAXHandler.startElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_SERVICE_ELEMENT_START:
|
||||
// Verify that we are processing the expected tag
|
||||
if (ProtoDefs.serviceElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_SERVICE_DATA;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("GetAuthPolicyReqMsg SAXHandler.startElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_HOST_ELEMENT_START:
|
||||
// Verify that we are processing the expected tag
|
||||
if (ProtoDefs.hostElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_HOST_DATA;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("GetAuthPolicyReqMsg SAXHandler.startElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
System.err.println("GetAuthPolicyReqMsg SAXHandler.startElement()- State error");
|
||||
throw new SAXException("State error");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* endElement() immplementation.
|
||||
*/
|
||||
public void endElement (String uri, String name, String qName) throws SAXException
|
||||
{
|
||||
// Proceed based on our state
|
||||
switch (m_state)
|
||||
{
|
||||
|
||||
case AWAITING_ROOT_ELEMENT_END:
|
||||
// Verify that we are processing the expected tag
|
||||
if (ProtoDefs.getAuthPolicyRequestElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = DONE_PARSING;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("GetAuthPolicyReqMsg SAXHandler.endElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_SERVICE_ELEMENT_END:
|
||||
// Verify that we are processing the expected tag
|
||||
if (ProtoDefs.serviceElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_HOST_ELEMENT_START;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("GetAuthPolicyReqMsg SAXHandler.endElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_HOST_ELEMENT_END:
|
||||
// Verify that we are processing the expected tag
|
||||
if (ProtoDefs.hostElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_ROOT_ELEMENT_END;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("GetAuthPolicyReqMsg SAXHandler.endElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
System.err.println("GetAuthPolicyReqMsg SAXHandler.startElement()- State error");
|
||||
throw new SAXException("State error");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* character() implementation.
|
||||
*/
|
||||
public void characters (char ch[], int start, int length) throws SAXException
|
||||
{
|
||||
// Proceed based on our state
|
||||
switch (m_state)
|
||||
{
|
||||
|
||||
case AWAITING_SERVICE_DATA:
|
||||
// Consume the data
|
||||
m_GetAuthPolicyReqMsg.m_serviceName = new String(ch, start, length);
|
||||
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_SERVICE_ELEMENT_END;
|
||||
break;
|
||||
|
||||
case AWAITING_HOST_DATA:
|
||||
// Consume the data
|
||||
m_GetAuthPolicyReqMsg.m_hostName = new String(ch, start, length);
|
||||
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_HOST_ELEMENT_END;
|
||||
break;
|
||||
|
||||
default:
|
||||
// Do nothing
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor
|
||||
*/
|
||||
public GetAuthPolicyReqMsg (InputStream inStream) throws Exception
|
||||
{
|
||||
try
|
||||
{
|
||||
// Parse the GetAuthPolicyReqMsg
|
||||
XMLReader xr = XMLReaderFactory.createXMLReader();
|
||||
SAXHandler handler = new SAXHandler(this);
|
||||
xr.setContentHandler(handler);
|
||||
xr.setErrorHandler(handler);
|
||||
|
||||
InputSource source = new InputSource(inStream);
|
||||
xr.parse(source);
|
||||
}
|
||||
catch (SAXException e)
|
||||
{
|
||||
System.err.println("GetAuthPolicyReqMsg()- Parse exception: " + e.toString());
|
||||
throw new Exception("Protocol error");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Method to get the service name.
|
||||
*/
|
||||
public String getServiceName() throws Exception
|
||||
{
|
||||
return m_serviceName;
|
||||
}
|
||||
|
||||
/*
|
||||
* Method to get the host name.
|
||||
*/
|
||||
public String getHostName() throws Exception
|
||||
{
|
||||
return m_hostName;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail,
|
||||
* you may find current contact information at www.novell.com.
|
||||
*
|
||||
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
package com.novell.casa.authtoksvc;
|
||||
|
||||
/**
|
||||
* GetAuthPolicyRespMsg Class.
|
||||
*
|
||||
* This class deals with the message sent to the Casa Client as a
|
||||
* response to a get authentication token request. The format of
|
||||
* the message is as follows when the response includes an
|
||||
* authentication token:
|
||||
*
|
||||
* <?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
* <get_auth_policy_resp>
|
||||
* <status><description>OK</description>200</status>
|
||||
* <auth_policy>authentication policy data</auth_policy>
|
||||
* </get_auth_policy_resp>
|
||||
*
|
||||
* The format of the message is as follows when the response does not
|
||||
* include an authentication token.
|
||||
*
|
||||
* <?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
* <get_auth_policy_resp>
|
||||
* <status><description>status description</description>status code</status>
|
||||
* </get_auth_policy_resp>
|
||||
*
|
||||
* Plase note that the protocol utilizes the status codes defined
|
||||
* in the HTTP 1.1 Specification.
|
||||
*
|
||||
*/
|
||||
public class GetAuthPolicyRespMsg
|
||||
{
|
||||
|
||||
String m_msg;
|
||||
|
||||
/*
|
||||
* Constructor for a msg that does not include the authentication policy.
|
||||
*/
|
||||
public GetAuthPolicyRespMsg (
|
||||
String statusDescription,
|
||||
String statusCode) throws Exception
|
||||
{
|
||||
// Get a StringBuffer to help us with the construction of the message
|
||||
StringBuffer sb = new StringBuffer();
|
||||
|
||||
// Start building the message
|
||||
sb.append(ProtoDefs.xmlDeclaration + "\r\n");
|
||||
sb.append("<" + ProtoDefs.getAuthPolicyResponseElementName + ">" + "\r\n");
|
||||
sb.append("<" + ProtoDefs.statusElementName + ">"
|
||||
+ "<" + ProtoDefs.descriptionElementName + ">" + statusDescription + "</" + ProtoDefs.descriptionElementName + ">"
|
||||
+ statusCode + "</" + ProtoDefs.statusElementName + ">" + "\r\n");
|
||||
sb.append("</" + ProtoDefs.getAuthPolicyResponseElementName + ">" + "\r\n");
|
||||
|
||||
// The message has now been built, save it.
|
||||
m_msg = sb.toString();
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor for a msg that includes the authentication policy.
|
||||
*/
|
||||
public GetAuthPolicyRespMsg (
|
||||
String statusDescription,
|
||||
String statusCode,
|
||||
String authPolicy) throws Exception
|
||||
{
|
||||
// Get a StringBuffer to help us with the construction of the message
|
||||
StringBuffer sb = new StringBuffer();
|
||||
|
||||
// Start building the message
|
||||
sb.append(ProtoDefs.xmlDeclaration + "\r\n");
|
||||
sb.append("<" + ProtoDefs.getAuthPolicyResponseElementName + ">" + "\r\n");
|
||||
sb.append("<" + ProtoDefs.statusElementName + ">"
|
||||
+ "<" + ProtoDefs.descriptionElementName + ">" + ProtoDefs.httpOkStatusMsg + "</" + ProtoDefs.descriptionElementName + ">"
|
||||
+ ProtoDefs.httpOkStatusCode + "</" + ProtoDefs.statusElementName + ">" + "\r\n");
|
||||
sb.append("<" + ProtoDefs.authPolicyElementName + ">" + authPolicy + "</" + ProtoDefs.authPolicyElementName + ">" + "\r\n");
|
||||
sb.append("</" + ProtoDefs.getAuthPolicyResponseElementName + ">" + "\r\n");
|
||||
|
||||
// The message has now been built, save it.
|
||||
m_msg = sb.toString();
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a string containing the GetAuthPolicyRespMsg.
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
return m_msg;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,331 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail,
|
||||
* you may find current contact information at www.novell.com.
|
||||
*
|
||||
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
package com.novell.casa.authtoksvc;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.XMLReader;
|
||||
import org.xml.sax.helpers.XMLReaderFactory;
|
||||
|
||||
/**
|
||||
* GetAuthTokReqMsg Class.
|
||||
*
|
||||
* This class deals with the message sent by Casa Client when requesting
|
||||
* a token to authenticate an entity to a particular service. The format of
|
||||
* the message is as follows:
|
||||
*
|
||||
* <?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
* <get_auth_token_req>
|
||||
* <service>service name</service>
|
||||
* <host>host name</host>
|
||||
* <session_token>session token data</session_token>
|
||||
* </get_auth_token_req>
|
||||
*
|
||||
*/
|
||||
public class GetAuthTokReqMsg
|
||||
{
|
||||
|
||||
protected String m_serviceName = null;
|
||||
protected String m_hostName = null;
|
||||
protected String m_sessionToken = null;
|
||||
|
||||
/*
|
||||
* Class for handling GetAuthTokReq msg parsing events.
|
||||
*/
|
||||
private class SAXHandler extends org.xml.sax.helpers.DefaultHandler
|
||||
{
|
||||
private final static int AWAITING_ROOT_ELEMENT_START = 0;
|
||||
private final static int AWAITING_ROOT_ELEMENT_END = 1;
|
||||
private final static int AWAITING_SERVICE_ELEMENT_START = 2;
|
||||
private final static int AWAITING_SERVICE_ELEMENT_END = 3;
|
||||
private final static int AWAITING_SERVICE_DATA = 4;
|
||||
private final static int AWAITING_HOST_ELEMENT_START = 5;
|
||||
private final static int AWAITING_HOST_ELEMENT_END = 6;
|
||||
private final static int AWAITING_HOST_DATA = 7;
|
||||
private final static int AWAITING_SESSION_TOKEN_ELEMENT_START = 8;
|
||||
private final static int AWAITING_SESSION_TOKEN_ELEMENT_END = 9;
|
||||
private final static int AWAITING_SESSION_TOKEN_DATA = 10;
|
||||
private final static int DONE_PARSING = 11;
|
||||
|
||||
private GetAuthTokReqMsg m_GetAuthTokReqMsg;
|
||||
private int m_state;
|
||||
|
||||
/*
|
||||
* Constructor
|
||||
*/
|
||||
public SAXHandler (GetAuthTokReqMsg GetAuthTokReqMsg)
|
||||
{
|
||||
super();
|
||||
|
||||
// Initialize our members
|
||||
m_GetAuthTokReqMsg = GetAuthTokReqMsg;
|
||||
m_state = AWAITING_ROOT_ELEMENT_START;
|
||||
}
|
||||
|
||||
/*
|
||||
* endDocument() implementation.
|
||||
*/
|
||||
public void endDocument () throws SAXException
|
||||
{
|
||||
// Verify that we obtained all of the required elements
|
||||
if (m_state != DONE_PARSING)
|
||||
{
|
||||
System.err.println("GetAuthTokReqMsg SAXHandler.endDocument()- Missing element");
|
||||
throw new SAXException("Missing element");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* startElement() implementation.
|
||||
*/
|
||||
public void startElement (String uri, String name, String qName, org.xml.sax.Attributes atts) throws SAXException
|
||||
{
|
||||
// Proceed based on our state
|
||||
switch (m_state)
|
||||
{
|
||||
|
||||
case AWAITING_ROOT_ELEMENT_START:
|
||||
// Verify that we are processing the expected tag
|
||||
if (ProtoDefs.getAuthTokRequestElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_SERVICE_ELEMENT_START;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("GetAuthTokReqMsg SAXHandler.startElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_SERVICE_ELEMENT_START:
|
||||
// Verify that we are processing the expected tag
|
||||
if (ProtoDefs.serviceElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_SERVICE_DATA;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("GetAuthTokReqMsg SAXHandler.startElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_HOST_ELEMENT_START:
|
||||
// Verify that we are processing the expected tag
|
||||
if (ProtoDefs.hostElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_HOST_DATA;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("GetAuthTokReqMsg SAXHandler.startElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case AWAITING_SESSION_TOKEN_ELEMENT_START:
|
||||
// Verify that we are processing the expected tag
|
||||
if (ProtoDefs.sessionTokenElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_SESSION_TOKEN_DATA;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("GetAuthTokReqMsg SAXHandler.startElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
System.err.println("GetAuthTokReqMsg SAXHandler.startElement()- State error");
|
||||
throw new SAXException("State error");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* endElement() immplementation.
|
||||
*/
|
||||
public void endElement (String uri, String name, String qName) throws SAXException
|
||||
{
|
||||
// Proceed based on our state
|
||||
switch (m_state)
|
||||
{
|
||||
|
||||
case AWAITING_ROOT_ELEMENT_END:
|
||||
// Verify that we are processing the expected tag
|
||||
if (ProtoDefs.getAuthTokRequestElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = DONE_PARSING;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("GetAuthTokReqMsg SAXHandler.endElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_SERVICE_ELEMENT_END:
|
||||
// Verify that we are processing the expected tag
|
||||
if (ProtoDefs.serviceElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_HOST_ELEMENT_START;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("GetAuthTokReqMsg SAXHandler.endElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_HOST_ELEMENT_END:
|
||||
// Verify that we are processing the expected tag
|
||||
if (ProtoDefs.hostElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_SESSION_TOKEN_ELEMENT_START;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("GetAuthTokReqMsg SAXHandler.endElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_SESSION_TOKEN_ELEMENT_END:
|
||||
// Verify that we are processing the expected tag
|
||||
if (ProtoDefs.sessionTokenElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_ROOT_ELEMENT_END;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("GetAuthTokReqMsg SAXHandler.endElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
System.err.println("GetAuthTokReqMsg SAXHandler.startElement()- State error");
|
||||
throw new SAXException("State error");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* character() implementation.
|
||||
*/
|
||||
public void characters (char ch[], int start, int length) throws SAXException
|
||||
{
|
||||
// Proceed based on our state
|
||||
switch (m_state)
|
||||
{
|
||||
|
||||
case AWAITING_SERVICE_DATA:
|
||||
// Consume the data
|
||||
m_GetAuthTokReqMsg.m_serviceName = new String(ch, start, length);
|
||||
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_SERVICE_ELEMENT_END;
|
||||
break;
|
||||
|
||||
case AWAITING_HOST_DATA:
|
||||
// Consume the data
|
||||
m_GetAuthTokReqMsg.m_hostName = new String(ch, start, length);
|
||||
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_HOST_ELEMENT_END;
|
||||
break;
|
||||
|
||||
case AWAITING_SESSION_TOKEN_DATA:
|
||||
// Consume the data
|
||||
m_GetAuthTokReqMsg.m_sessionToken = new String(ch, start, length);
|
||||
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_SESSION_TOKEN_ELEMENT_END;
|
||||
break;
|
||||
|
||||
default:
|
||||
// Do nothing
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor
|
||||
*/
|
||||
public GetAuthTokReqMsg (InputStream inStream) throws Exception
|
||||
{
|
||||
try
|
||||
{
|
||||
// Parse the GetAuthTokReqMsg
|
||||
XMLReader xr = XMLReaderFactory.createXMLReader();
|
||||
SAXHandler handler = new SAXHandler(this);
|
||||
xr.setContentHandler(handler);
|
||||
xr.setErrorHandler(handler);
|
||||
|
||||
InputSource source = new InputSource(inStream);
|
||||
xr.parse(source);
|
||||
}
|
||||
catch (SAXException e)
|
||||
{
|
||||
System.err.println("GetAuthTokReqMsg()- Parse exception: " + e.toString());
|
||||
throw new Exception("Protocol error");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Method to get the service name.
|
||||
*/
|
||||
public String getServiceName() throws Exception
|
||||
{
|
||||
return m_serviceName;
|
||||
}
|
||||
|
||||
/*
|
||||
* Method to get the host name.
|
||||
*/
|
||||
public String getHostName() throws Exception
|
||||
{
|
||||
return m_hostName;
|
||||
}
|
||||
|
||||
/*
|
||||
* Method to get the session token.
|
||||
*/
|
||||
public String getSessionToken() throws Exception
|
||||
{
|
||||
return m_sessionToken;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail,
|
||||
* you may find current contact information at www.novell.com.
|
||||
*
|
||||
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
package com.novell.casa.authtoksvc;
|
||||
|
||||
/**
|
||||
* GetAuthTokRespMsg Class.
|
||||
*
|
||||
* This class deals with the message sent to the Casa Client as a
|
||||
* response to a get authentication token request. The format of
|
||||
* the message is as follows when the response includes an
|
||||
* authentication token:
|
||||
*
|
||||
* <?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
* <get_auth_tok_resp>
|
||||
* <status><description>OK</description>200</status>
|
||||
* <auth_token><lifetime>lifetime value</lifetime>authentication token data</auth_token>
|
||||
* </get_auth_tok_resp>
|
||||
*
|
||||
* The format of the message is as follows when the response does not
|
||||
* include an authentication token.
|
||||
*
|
||||
* <?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
* <get_auth_tok_resp>
|
||||
* <status><description>status description</description>status code</status>
|
||||
* </get_auth_tok_resp>
|
||||
*
|
||||
* Plase note that the protocol utilizes the status codes defined
|
||||
* in the HTTP 1.1 Specification.
|
||||
*
|
||||
*/
|
||||
public class GetAuthTokRespMsg
|
||||
{
|
||||
|
||||
String m_msg;
|
||||
|
||||
/*
|
||||
* Constructor for a msg that does not include the authentication token.
|
||||
*/
|
||||
public GetAuthTokRespMsg (
|
||||
String statusDescription,
|
||||
String statusCode) throws Exception
|
||||
{
|
||||
// Get a StringBuffer to help us with the construction of the message
|
||||
StringBuffer sb = new StringBuffer();
|
||||
|
||||
// Start building the message
|
||||
sb.append(ProtoDefs.xmlDeclaration + "\r\n");
|
||||
sb.append("<" + ProtoDefs.getAuthTokResponseElementName + ">" + "\r\n");
|
||||
sb.append("<" + ProtoDefs.statusElementName + ">"
|
||||
+ "<" + ProtoDefs.descriptionElementName + ">" + statusDescription + "</" + ProtoDefs.descriptionElementName + ">"
|
||||
+ statusCode + "</" + ProtoDefs.statusElementName + ">" + "\r\n");
|
||||
sb.append("</" + ProtoDefs.getAuthTokResponseElementName + ">" + "\r\n");
|
||||
|
||||
// The message has now been built, save it.
|
||||
m_msg = sb.toString();
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor for a msg that includes the authentication token.
|
||||
*/
|
||||
public GetAuthTokRespMsg (
|
||||
String statusDescription,
|
||||
String statusCode,
|
||||
String authToken,
|
||||
String authTokenLifetime) throws Exception
|
||||
{
|
||||
// Get a StringBuffer to help us with the construction of the message
|
||||
StringBuffer sb = new StringBuffer();
|
||||
|
||||
// Start building the message
|
||||
sb.append(ProtoDefs.xmlDeclaration + "\r\n");
|
||||
sb.append("<" + ProtoDefs.getAuthTokResponseElementName + ">" + "\r\n");
|
||||
sb.append("<" + ProtoDefs.statusElementName + ">"
|
||||
+ "<" + ProtoDefs.descriptionElementName + ">" + ProtoDefs.httpOkStatusMsg + "</" + ProtoDefs.descriptionElementName + ">"
|
||||
+ ProtoDefs.httpOkStatusCode + "</" + ProtoDefs.statusElementName + ">" + "\r\n");
|
||||
sb.append("<" + ProtoDefs.authTokenElementName + ">"
|
||||
+ "<" + ProtoDefs.lifetimeElementName + ">" + authTokenLifetime + "</" + ProtoDefs.lifetimeElementName + ">"
|
||||
+ authToken + "</" + ProtoDefs.authTokenElementName + ">" + "\r\n");
|
||||
sb.append("</" + ProtoDefs.getAuthTokResponseElementName + ">" + "\r\n");
|
||||
|
||||
// The message has now been built, save it.
|
||||
m_msg = sb.toString();
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a string containing the GetAuthTokRespMsg.
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
return m_msg;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail,
|
||||
* you may find current contact information at www.novell.com.
|
||||
*
|
||||
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
package com.novell.casa.authtoksvc;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
/**
|
||||
* GetAuthToken Class.
|
||||
*
|
||||
* This class processes requests for tokens to authenticate an entity
|
||||
* to a particular service.
|
||||
*
|
||||
*/
|
||||
public class GetAuthToken implements RpcMethod
|
||||
{
|
||||
private SvcConfig m_svcConfig;
|
||||
private EnabledSvcsConfig m_enabledSvcsConfig;
|
||||
|
||||
/*
|
||||
* Constructor.
|
||||
*/
|
||||
public GetAuthToken() throws Exception
|
||||
{
|
||||
// Nothing to do at this time
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the Rpc method.
|
||||
*/
|
||||
public void init(SvcConfig svcConfig, EnabledSvcsConfig enabledSvcsConfig) throws Exception
|
||||
{
|
||||
m_svcConfig = svcConfig;
|
||||
m_enabledSvcsConfig = enabledSvcsConfig;
|
||||
}
|
||||
|
||||
/*
|
||||
* Process Rpc.
|
||||
*/
|
||||
public void invoke(InputStream inStream, PrintWriter out) throws IOException
|
||||
{
|
||||
try
|
||||
{
|
||||
System.err.println("GetAuthToken.invoke()");
|
||||
|
||||
// Parse the GetAuthTokReqMsg sent from the client
|
||||
GetAuthTokReqMsg getAuthTokReqMsg = new GetAuthTokReqMsg(inStream);
|
||||
|
||||
// Verify that the service is enabled
|
||||
if (m_enabledSvcsConfig.svcEnabled(getAuthTokReqMsg.getHostName(),
|
||||
getAuthTokReqMsg.getServiceName()))
|
||||
{
|
||||
// Now create a session token (This validates the session token provided).
|
||||
SessionToken sessionToken = new SessionToken(getAuthTokReqMsg.getSessionToken());
|
||||
|
||||
try
|
||||
{
|
||||
// Create the Authentication Token
|
||||
AuthToken authToken = new AuthToken(sessionToken.getIdentId(),
|
||||
sessionToken.getRealm(),
|
||||
getAuthTokReqMsg.getServiceName(),
|
||||
getAuthTokReqMsg.getHostName(),
|
||||
m_svcConfig,
|
||||
m_enabledSvcsConfig);
|
||||
|
||||
// Write out the response
|
||||
GetAuthTokRespMsg getAuthTokRespMsg = new GetAuthTokRespMsg(ProtoDefs.httpOkStatusMsg,
|
||||
ProtoDefs.httpOkStatusCode,
|
||||
authToken.toString(),
|
||||
authToken.getLifetime());
|
||||
out.println(getAuthTokRespMsg.toString());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
System.err.println("GetAuthToken.invoke()- Exception: " + e.toString());
|
||||
|
||||
// Write out the response
|
||||
try
|
||||
{
|
||||
GetAuthTokRespMsg getAuthTokRespMsg = new GetAuthTokRespMsg(ProtoDefs.httpUnauthorizedStatusMsg,
|
||||
ProtoDefs.httpUnauthorizedStatusCode);
|
||||
out.println(getAuthTokRespMsg.toString());
|
||||
}
|
||||
catch (Exception e2)
|
||||
{
|
||||
System.err.println("GetAuthToken.invoke()- Exception trying to construct response msg: " + e2.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// The service has not been enabled to utilize our authentication tokens
|
||||
GetAuthTokRespMsg getAuthTokRespMsg = new GetAuthTokRespMsg(ProtoDefs.httpNotFoundStatusMsg,
|
||||
ProtoDefs.httpNotFoundStatusCode);
|
||||
out.println(getAuthTokRespMsg.toString());
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
System.err.println("GetAuthToken.invoke()- Exception: " + e.toString());
|
||||
|
||||
// Write out the response
|
||||
try
|
||||
{
|
||||
GetAuthTokRespMsg getAuthTokRespMsg = new GetAuthTokRespMsg(ProtoDefs.httpServerErrorStatusMsg,
|
||||
ProtoDefs.httpServerErrorStatusCode);
|
||||
out.println(getAuthTokRespMsg.toString());
|
||||
}
|
||||
catch (Exception e2)
|
||||
{
|
||||
System.err.println("GetAuthToken.invoke()- Exception trying to construct response msg: " + e2.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the method id.
|
||||
*/
|
||||
public String getId()
|
||||
{
|
||||
return "GetAuthToken";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,294 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail,
|
||||
* you may find current contact information at www.novell.com.
|
||||
*
|
||||
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
package com.novell.casa.authtoksvc;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.XMLReader;
|
||||
import org.xml.sax.helpers.XMLReaderFactory;
|
||||
|
||||
/**
|
||||
* IdenTokenConfig Class.
|
||||
*
|
||||
* This class obtains and maintains identity token configuration.
|
||||
*
|
||||
*/
|
||||
public class IdenTokenConfig
|
||||
{
|
||||
// Well known identity token configuration settings
|
||||
public final static String EncryptAttributes = "EncryptAttributes";
|
||||
public final static String Attributes = "Attributes";
|
||||
|
||||
// Default configuration values
|
||||
private String m_defaultEncryptAttributesValue = "false";
|
||||
private String m_defaultAttributesValue = "sn";
|
||||
|
||||
private Map m_tokenSettingsMap;
|
||||
private String[] m_identityAttributes;
|
||||
|
||||
/*
|
||||
* Class for handling parsing events.
|
||||
*/
|
||||
private class SAXHandler extends org.xml.sax.helpers.DefaultHandler
|
||||
{
|
||||
private final static int AWAITING_ROOT_ELEMENT_START = 0;
|
||||
private final static int AWAITING_SETTING_ELEMENT_START = 1;
|
||||
private final static int AWAITING_SETTING_ELEMENT_DATA = 2;
|
||||
private final static int AWAITING_SETTING_ELEMENT_END = 3;
|
||||
private final static int DONE_PARSING = 4;
|
||||
|
||||
private final static String m_rootElementName = "settings";
|
||||
|
||||
private Map m_keyMap;
|
||||
private int m_state;
|
||||
private String m_currentKey;
|
||||
|
||||
/*
|
||||
* Constructor
|
||||
*/
|
||||
public SAXHandler(Map keyMap)
|
||||
{
|
||||
super();
|
||||
|
||||
// Initialize our members
|
||||
m_keyMap = keyMap;
|
||||
m_state = AWAITING_ROOT_ELEMENT_START;
|
||||
}
|
||||
|
||||
/*
|
||||
* endDocument() implementation.
|
||||
*/
|
||||
public void endDocument () throws SAXException
|
||||
{
|
||||
// Verify that we are not in an invalid state
|
||||
if (m_state != DONE_PARSING)
|
||||
{
|
||||
System.err.println("IdenTokenConfig SAXHandler.endDocument()- Invalid state" + m_state);
|
||||
throw new SAXException("Invalid state at endDocument");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* startElement() implementation.
|
||||
*/
|
||||
public void startElement (String uri, String name, String qName, org.xml.sax.Attributes atts) throws SAXException
|
||||
{
|
||||
// Proceed based on our state
|
||||
switch (m_state)
|
||||
{
|
||||
case AWAITING_ROOT_ELEMENT_START:
|
||||
// Verify that we are processing the expected tag
|
||||
if (m_rootElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_SETTING_ELEMENT_START;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("IdenTokenConfig SAXHandler.startElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_SETTING_ELEMENT_START:
|
||||
// Keep track of the key name
|
||||
m_currentKey = qName;
|
||||
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_SETTING_ELEMENT_DATA;
|
||||
break;
|
||||
|
||||
default:
|
||||
System.err.println("IdenTokenConfig SAXHandler.startElement()- Invalid state " + m_state);
|
||||
throw new SAXException("Invalid state at startElement");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* endElement() immplementation.
|
||||
*/
|
||||
public void endElement (String uri, String name, String qName) throws SAXException
|
||||
{
|
||||
// Proceed based on our state
|
||||
switch (m_state)
|
||||
{
|
||||
case AWAITING_SETTING_ELEMENT_DATA:
|
||||
case AWAITING_SETTING_ELEMENT_END:
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_SETTING_ELEMENT_START;
|
||||
break;
|
||||
|
||||
case AWAITING_SETTING_ELEMENT_START:
|
||||
// Verify that we are processing the expected tag
|
||||
if (m_rootElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = DONE_PARSING;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("IdenTokenConfig SAXHandler.endElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
System.err.println("IdenTokenConfig SAXHandler.endElement()- Invalid state " + m_state);
|
||||
throw new SAXException("Invalid state at endElement");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* character() implementation.
|
||||
*/
|
||||
public void characters (char ch[], int start, int length) throws SAXException
|
||||
{
|
||||
// Consume the data if in the right state
|
||||
if (m_state == AWAITING_SETTING_ELEMENT_DATA)
|
||||
{
|
||||
// Consume the data and add the key to map
|
||||
// tbd - Add code to aggregate attributes specified as multiple elements
|
||||
m_keyMap.put(m_currentKey, new String(ch, start, length));
|
||||
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_SETTING_ELEMENT_END;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor which sets default configuration values.
|
||||
*/
|
||||
public IdenTokenConfig() throws Exception
|
||||
{
|
||||
System.err.println("IdenTokenConfig()- Default");
|
||||
|
||||
// Create a map to keep track of the token settings
|
||||
m_tokenSettingsMap = new HashMap();
|
||||
|
||||
// Set the default settings in our map
|
||||
m_tokenSettingsMap.put(Attributes, m_defaultAttributesValue);
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor.
|
||||
*/
|
||||
public IdenTokenConfig(String idenTokenSettingsFileName) throws Exception
|
||||
{
|
||||
System.err.println("IdenTokenConfig()-");
|
||||
|
||||
// Create a map to keep track of the token settings
|
||||
m_tokenSettingsMap = new HashMap();
|
||||
|
||||
try
|
||||
{
|
||||
// Get an input stream to read from the token settings file
|
||||
File f = new File(idenTokenSettingsFileName);
|
||||
FileInputStream inStream = new FileInputStream(f);
|
||||
|
||||
// Parse the file
|
||||
XMLReader xr = XMLReaderFactory.createXMLReader();
|
||||
SAXHandler handler = new SAXHandler(m_tokenSettingsMap);
|
||||
xr.setContentHandler(handler);
|
||||
xr.setErrorHandler(handler);
|
||||
|
||||
InputSource source = new InputSource(inStream);
|
||||
xr.parse(source);
|
||||
|
||||
inStream.close();
|
||||
|
||||
// Process the specified attributes
|
||||
if (m_tokenSettingsMap.containsKey(Attributes) == false)
|
||||
{
|
||||
System.err.println("IdenTokenConfig()- Attributes not configured, defaulting them.");
|
||||
m_tokenSettingsMap.put(Attributes, m_defaultAttributesValue);
|
||||
}
|
||||
String attributes = (String) m_tokenSettingsMap.get(Attributes);
|
||||
m_identityAttributes = attributes.split(",");
|
||||
}
|
||||
catch (SAXException e)
|
||||
{
|
||||
System.err.println("IdenTokenConfig()- " + idenTokenSettingsFileName + " format error, exception: " + e.toString());
|
||||
throw new Exception("IdenTokenConfig()- authtoken.settings format error");
|
||||
}
|
||||
catch (SecurityException e)
|
||||
{
|
||||
System.err.println("IdenTokenConfig()- SecurityException accessing " + idenTokenSettingsFileName + " Exception=" + e.toString());
|
||||
throw new Exception("IdenTokenConfig()- Not able to access file");
|
||||
}
|
||||
catch (FileNotFoundException e)
|
||||
{
|
||||
System.err.println("IdenTokenConfig()- File " + idenTokenSettingsFileName + " not found");
|
||||
throw new Exception("IdenTokenConfig()- File not found");
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
System.err.println("IdenTokenConfig()- IOException accessing " + idenTokenSettingsFileName + " Exception=" + e.toString());
|
||||
throw new Exception("IdenTokenConfig()- Read error");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the value associated with the specified setting.
|
||||
*/
|
||||
public String getSetting(String settingName) throws Exception
|
||||
{
|
||||
// Try to find the setting in our map
|
||||
String value = (String) m_tokenSettingsMap.get(settingName);
|
||||
if (value == null)
|
||||
{
|
||||
System.err.println("IdenTokenConfig.getSetting()- Did not find setting " + settingName);
|
||||
|
||||
// The setting is not in our map, check if it is one to
|
||||
// which we have defaults.
|
||||
if (settingName.equals(EncryptAttributes) == true)
|
||||
{
|
||||
value = m_defaultEncryptAttributesValue;
|
||||
System.err.println("AuthTokenConfig.getSetting()- Assigning default value " + value);
|
||||
|
||||
// Add the key to the map so that it can be found quicker next time
|
||||
m_tokenSettingsMap.put(EncryptAttributes, m_defaultEncryptAttributesValue);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("IdenTokenConfig.getSetting()- Found setting " + settingName);
|
||||
System.err.println("IdenTokenConfig.getSetting()- Setting value = " + value);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the identity attributes that must be included in the token.
|
||||
*/
|
||||
public String[] getAttributes() throws Exception
|
||||
{
|
||||
return m_identityAttributes;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail,
|
||||
* you may find current contact information at www.novell.com.
|
||||
*
|
||||
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
package com.novell.casa.authtoksvc;
|
||||
|
||||
/*
|
||||
* IdentityToken Interface.
|
||||
*
|
||||
* This is the interface implemented by Identity Token Providers.
|
||||
*/
|
||||
public interface IdentityToken
|
||||
{
|
||||
/*
|
||||
* Initialize the token with parameters.
|
||||
*/
|
||||
void initialize(String identityId,
|
||||
String sourceName,
|
||||
String targetService,
|
||||
String targetHost,
|
||||
SvcConfig svcConfig) throws Exception;
|
||||
|
||||
/*
|
||||
* Initialize the token object with encoded token string.
|
||||
*/
|
||||
void initialize(String encodedToken) throws Exception;
|
||||
|
||||
/*
|
||||
* Returns encoded token string.
|
||||
*
|
||||
* IMPORTANT: The token string can not contain the substring "]]>"
|
||||
* within it.
|
||||
*/
|
||||
String getEncodedToken() throws Exception;
|
||||
|
||||
/*
|
||||
* Returns a string containing the identity token provider type.
|
||||
*/
|
||||
String getProviderType() throws Exception;
|
||||
|
||||
/*
|
||||
* Returns a string containing the identity id.
|
||||
*/
|
||||
String getIdentityId() throws Exception;
|
||||
|
||||
/*
|
||||
* Returns a string containing the name associated with the
|
||||
* identity source.
|
||||
*/
|
||||
String getSourceName() throws Exception;
|
||||
|
||||
/*
|
||||
* Returns a string containing the url associated with the
|
||||
* identity source.
|
||||
*/
|
||||
String getSourceUrl() throws Exception;
|
||||
|
||||
/*
|
||||
* Returns a string containing the name of the targeted service.
|
||||
*/
|
||||
String getTargetService() throws Exception;
|
||||
|
||||
/*
|
||||
* Returns a string containig the name of the host where the
|
||||
* targeted service resides.
|
||||
*/
|
||||
String getTargetHost() throws Exception;
|
||||
|
||||
/*
|
||||
* Returns the attributes of the identity.
|
||||
*/
|
||||
javax.naming.directory.Attributes getAttributes() throws Exception;
|
||||
}
|
||||
@@ -0,0 +1,257 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail,
|
||||
* you may find current contact information at www.novell.com.
|
||||
*
|
||||
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
package com.novell.casa.authtoksvc;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Hashtable;
|
||||
|
||||
import javax.naming.Context;
|
||||
import javax.naming.NamingEnumeration;
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.directory.Attributes;
|
||||
import javax.naming.directory.BasicAttribute;
|
||||
import javax.naming.directory.BasicAttributes;
|
||||
import javax.naming.directory.DirContext;
|
||||
import javax.naming.directory.InitialDirContext;
|
||||
import javax.naming.directory.SearchResult;
|
||||
import javax.naming.directory.SearchControls;
|
||||
|
||||
import org.ietf.jgss.GSSContext;
|
||||
import org.ietf.jgss.GSSCredential;
|
||||
import org.ietf.jgss.GSSException;
|
||||
import org.ietf.jgss.GSSManager;
|
||||
import org.ietf.jgss.GSSName;
|
||||
import org.ietf.jgss.Oid;
|
||||
|
||||
import org.bandit.ia.IAContext;
|
||||
|
||||
/**
|
||||
* Krb5Authenticate Class.
|
||||
*
|
||||
* This class implementes an authentication mechanism for
|
||||
* the processing of authentication requests utilizing a
|
||||
* Kerberos5 token.
|
||||
*
|
||||
*/
|
||||
public class Krb5Authenticate implements AuthMechanism, Serializable
|
||||
{
|
||||
private static final String ServicePrincipalNameSetting = "ServicePrincipalName";
|
||||
|
||||
private SvcConfig m_svcConfig;
|
||||
private AuthMechConfig m_mechConfig;
|
||||
|
||||
/*
|
||||
* GSS Long Lived variables
|
||||
*/
|
||||
protected GSSManager m_manager;
|
||||
protected Oid m_krb5;
|
||||
protected GSSName m_svcName;
|
||||
protected GSSCredential m_credential;
|
||||
|
||||
/*
|
||||
* Krb5 Token Class.
|
||||
*/
|
||||
private class Krb5Token
|
||||
{
|
||||
private String m_principalName = "";
|
||||
|
||||
/*
|
||||
* The format of the Krb5 token is as follows:
|
||||
*
|
||||
* Base64.encode(GSS-API Token data));
|
||||
*/
|
||||
public Krb5Token(String encodedToken, Krb5Authenticate parent) throws Exception
|
||||
{
|
||||
// Decode the token
|
||||
char[] tokenChars = new char[encodedToken.length()];
|
||||
encodedToken.getChars(0, tokenChars.length, tokenChars, 0);
|
||||
byte[] tokenBytes = Base64Coder.decode(tokenChars);
|
||||
|
||||
try
|
||||
{
|
||||
// Create a context and validate the token
|
||||
GSSContext context = parent.m_manager.createContext(parent.m_credential);
|
||||
System.err.println("tokenLength = " + tokenBytes.length);
|
||||
context.acceptSecContext(tokenBytes, 0, tokenBytes.length);
|
||||
|
||||
// Save the principal name of the authenticated entity
|
||||
GSSName principalName = context.getSrcName();
|
||||
m_principalName = principalName.toString();
|
||||
|
||||
// Clean up
|
||||
context.dispose();
|
||||
}
|
||||
catch (GSSException e)
|
||||
{
|
||||
System.err.println("Krb5Authenticate Krb5Token()- GSS Exception caught: " + e.getLocalizedMessage());
|
||||
throw new Exception("Authentication Failure");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the name of the authenticated principal
|
||||
*/
|
||||
public String getPrincipalName()
|
||||
{
|
||||
return m_principalName;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor
|
||||
*/
|
||||
public Krb5Authenticate() throws Exception
|
||||
{
|
||||
// Nothing to do at this time
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the mechanism.
|
||||
*/
|
||||
public void init(SvcConfig svcConfig, AuthMechConfig mechConfig) throws Exception
|
||||
{
|
||||
m_svcConfig = svcConfig;
|
||||
m_mechConfig = mechConfig;
|
||||
|
||||
String servicePrincipal = mechConfig.getSetting(ServicePrincipalNameSetting);
|
||||
if (servicePrincipal != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Initalize our GSS variables
|
||||
//
|
||||
// Get an instance of the default GSSManager
|
||||
m_manager = GSSManager.getInstance();
|
||||
|
||||
// Create an OID specifying the Krb5 mechanism
|
||||
m_krb5 = new Oid("1.2.840.113554.1.2.2");
|
||||
|
||||
// Create our host based service name
|
||||
m_svcName = m_manager.createName(servicePrincipal,
|
||||
GSSName.NT_HOSTBASED_SERVICE,
|
||||
m_krb5);
|
||||
|
||||
// Now acquire our credentials
|
||||
m_credential = m_manager.createCredential(m_svcName,
|
||||
GSSCredential.INDEFINITE_LIFETIME,
|
||||
m_krb5,
|
||||
GSSCredential.ACCEPT_ONLY);
|
||||
}
|
||||
catch (GSSException e)
|
||||
{
|
||||
System.err.println("Krb5Authenticate()- GSS Exception caught: " + e.getLocalizedMessage());
|
||||
throw new Exception("Failed to instantiate needed GSS objects");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("Krb5Authenticate()- Service Principal Name not configured");
|
||||
throw new Exception("Service Principal Name not configured");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* invoke() implementation.
|
||||
*/
|
||||
public String invoke(AuthReqMsg authReqMsg) throws Exception
|
||||
{
|
||||
String identId = null;
|
||||
|
||||
try
|
||||
{
|
||||
System.err.println("Krb5Authenticate.invoke()");
|
||||
|
||||
// Now parse the Kerberos Token
|
||||
Krb5Token krb5Token = new Krb5Token(authReqMsg.getAuthMechToken(), this);
|
||||
|
||||
// Open a directory context and use it to identify the users
|
||||
// associated with the specified surname.
|
||||
Hashtable env = new Hashtable();
|
||||
env.put(Context.INITIAL_CONTEXT_FACTORY, "org.bandit.ia.IAInitialCtxFactory");
|
||||
env.put(IAContext.IA_REALM_CONFIG_LOCATION, m_svcConfig.getSetting(SvcConfig.IdentityAbstractionConfigFile));
|
||||
env.put(IAContext.IA_REALM_SELECTOR, authReqMsg.getRealm());
|
||||
|
||||
DirContext ctx = new InitialDirContext(env);
|
||||
|
||||
// Now search for a user with a matching kerberos principal name.
|
||||
//
|
||||
// Set up a search control so that the search is scoped to the sub-tree
|
||||
SearchControls controls = new SearchControls();
|
||||
controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
|
||||
|
||||
// Obtain the start search context - tbd - this will be removed once the functionality flows into Bandit
|
||||
String searchContext = m_svcConfig.getSetting(SvcConfig.StartSearchContext);
|
||||
if (searchContext == null)
|
||||
{
|
||||
// A start search context was not configured, start from the root.
|
||||
searchContext = "";
|
||||
}
|
||||
|
||||
// Perform the search
|
||||
NamingEnumeration answer = ctx.search(searchContext,
|
||||
"(krbPrincipalName={0})",
|
||||
new String[] {krb5Token.getPrincipalName()},
|
||||
controls);
|
||||
|
||||
// Proceed based on the result of the search
|
||||
if (answer.hasMore())
|
||||
{
|
||||
// The search succeeded, set the identity id.
|
||||
SearchResult sr = (SearchResult)answer.next();
|
||||
if (searchContext.equals(""))
|
||||
{
|
||||
identId = sr.getName();
|
||||
}
|
||||
else
|
||||
{
|
||||
identId = sr.getName() + "," + searchContext;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (NamingException e)
|
||||
{
|
||||
// Log the error
|
||||
System.err.println("Krb5Authenticate.invoke()- NamingException: " + e.getExplanation());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
System.err.println("Krb5Authenticate.invoke()- Exception: " + e.toString());
|
||||
}
|
||||
|
||||
// Return the authentication result
|
||||
return identId;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the mechanism id.
|
||||
*/
|
||||
public String getId()
|
||||
{
|
||||
return "Krb5Authenticate";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<settings>
|
||||
<description>This is the authentication mechanism for the Krb5Authenticate scheme. The Krb5Authenticate scheme authenticates entities using Kerberos-V tokens.</description>
|
||||
<ClassName>com.novell.casa.authtoksvc.Krb5Authenticate</ClassName>
|
||||
<RelativeClassPath>WEB-INF/classes</RelativeClassPath>
|
||||
<ServicePrincipalName>Specify the service's kerberos principal name</ServicePrincipalName>
|
||||
</settings>
|
||||
@@ -0,0 +1,86 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail,
|
||||
* you may find current contact information at www.novell.com.
|
||||
*
|
||||
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
package com.novell.casa.authtoksvc;
|
||||
|
||||
/*
|
||||
* ProDefs Class.
|
||||
*
|
||||
* This class contains constants utilized in the Casa Client/Server
|
||||
* protocol.
|
||||
*
|
||||
*/
|
||||
public class ProtoDefs
|
||||
{
|
||||
|
||||
/*
|
||||
* XML Declaration used in the Casa Client/Server protocol
|
||||
*/
|
||||
public final static String xmlDeclaration = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>";
|
||||
|
||||
/*
|
||||
* XML Element Name Constants for the documents exchanged between the
|
||||
* Casa Client and the Casa Server.
|
||||
*/
|
||||
public final static String authRequestElementName = "auth_req";
|
||||
public final static String authResponseElementName = "auth_resp";
|
||||
public final static String getAuthPolicyRequestElementName = "get_auth_policy_req";
|
||||
public final static String getAuthPolicyResponseElementName = "get_auth_policy_resp";
|
||||
public final static String getAuthTokRequestElementName = "get_auth_tok_req";
|
||||
public final static String getAuthTokResponseElementName = "get_auth_tok_resp";
|
||||
public final static String authMechTokenElementName = "auth_mech_token";
|
||||
public final static String statusElementName = "status";
|
||||
public final static String sessionTokenElementName = "session_token";
|
||||
public final static String authTokenElementName = "auth_token";
|
||||
public final static String authPolicyElementName = "auth_policy";
|
||||
public final static String identTokenElementName = "ident_token";
|
||||
public final static String lifetimeElementName = "lifetime";
|
||||
public final static String signatureElementName = "signature";
|
||||
public final static String typeElementName = "type";
|
||||
public final static String descriptionElementName = "description";
|
||||
public final static String serviceElementName = "service";
|
||||
public final static String hostElementName = "host";
|
||||
public final static String identIdElementName = "ident_id";
|
||||
public final static String realmElementName = "realm";
|
||||
public final static String authSourceElementName = "auth_source";
|
||||
public final static String mechanismElementName = "mechanism";
|
||||
public final static String mechanismInfoElementName = "mechanism_info";
|
||||
|
||||
/*
|
||||
* Configurable operating parameters
|
||||
*/
|
||||
public String sessionTokenLifetime = "360";
|
||||
|
||||
/*
|
||||
* HTTP Status Codes and Messages
|
||||
*/
|
||||
public final static String httpOkStatusCode = "200";
|
||||
public final static String httpOkStatusMsg = "OK";
|
||||
public final static String httpUnauthorizedStatusCode = "401";
|
||||
public final static String httpUnauthorizedStatusMsg = "Unauthorized";
|
||||
public final static String httpNotFoundStatusCode = "404";
|
||||
public final static String httpNotFoundStatusMsg = "Not Found";
|
||||
public final static String httpServerErrorStatusCode = "500";
|
||||
public final static String httpServerErrorStatusMsg = "Internal Server Error";
|
||||
}
|
||||
@@ -0,0 +1,223 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail,
|
||||
* you may find current contact information at www.novell.com.
|
||||
*
|
||||
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
package com.novell.casa.authtoksvc;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringReader;
|
||||
import java.util.Hashtable;
|
||||
|
||||
import javax.naming.Context;
|
||||
import javax.naming.NamingEnumeration;
|
||||
import javax.naming.directory.BasicAttribute;
|
||||
import javax.naming.directory.BasicAttributes;
|
||||
import javax.naming.directory.InitialDirContext;
|
||||
import javax.naming.directory.DirContext;
|
||||
import javax.naming.directory.Attributes;
|
||||
import javax.naming.directory.SearchResult;
|
||||
import javax.naming.directory.SearchControls;
|
||||
import javax.naming.NamingException;
|
||||
|
||||
import org.bandit.ia.IAContext;
|
||||
|
||||
|
||||
/**
|
||||
* PwdAuthenticate Class.
|
||||
*
|
||||
* This class implementes an authentication mechanism for
|
||||
* the processing of authentication requests utilizing a
|
||||
* username/password token.
|
||||
*
|
||||
*/
|
||||
public class PwdAuthenticate implements AuthMechanism, Serializable
|
||||
{
|
||||
private SvcConfig m_svcConfig;
|
||||
private AuthMechConfig m_mechConfig;
|
||||
|
||||
/*
|
||||
* Password Token Class.
|
||||
*/
|
||||
private class PwToken
|
||||
{
|
||||
private String m_username = "";
|
||||
private String m_password = "";
|
||||
|
||||
/*
|
||||
* The format of the Pw token is as follows:
|
||||
*
|
||||
* Base64.encode(new String("username\r\n" + "password\r\n"));
|
||||
*/
|
||||
public PwToken(String encodedToken) throws IOException
|
||||
{
|
||||
// Decode the token
|
||||
String token = Base64Coder.decode(encodedToken);
|
||||
|
||||
BufferedReader tokenReader = new BufferedReader(new StringReader(token));
|
||||
|
||||
// The second line contains the "username"
|
||||
m_username = tokenReader.readLine();
|
||||
|
||||
// The third line contains the "password"
|
||||
m_password = tokenReader.readLine();
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the username
|
||||
*/
|
||||
public String getUsername()
|
||||
{
|
||||
return m_username;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the password
|
||||
*/
|
||||
public String getPassword()
|
||||
{
|
||||
return m_password;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor
|
||||
*/
|
||||
public PwdAuthenticate() throws Exception
|
||||
{
|
||||
// Nothing to do at this time
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the mechanism.
|
||||
*/
|
||||
public void init(SvcConfig svcConfig, AuthMechConfig mechConfig) throws Exception
|
||||
{
|
||||
m_svcConfig = svcConfig;
|
||||
m_mechConfig = mechConfig;
|
||||
}
|
||||
|
||||
/*
|
||||
* invoke() implementation.
|
||||
*/
|
||||
public String invoke(AuthReqMsg authReqMsg) throws Exception
|
||||
{
|
||||
String identId = null;
|
||||
|
||||
try
|
||||
{
|
||||
System.err.println("PwdAuthenticate.invoke()");
|
||||
|
||||
// Now parse the PW Token
|
||||
PwToken pwToken = new PwToken(authReqMsg.getAuthMechToken());
|
||||
|
||||
// Open a directory context and use it to identify the users
|
||||
// associated with the specified surname.
|
||||
Hashtable env = new Hashtable();
|
||||
env.put(Context.INITIAL_CONTEXT_FACTORY, "org.bandit.ia.IAInitialCtxFactory");
|
||||
env.put(IAContext.IA_REALM_CONFIG_LOCATION, m_svcConfig.getSetting(SvcConfig.IdentityAbstractionConfigFile));
|
||||
env.put(IAContext.IA_REALM_SELECTOR, authReqMsg.getRealm());
|
||||
|
||||
DirContext ctx = new InitialDirContext(env);
|
||||
|
||||
// Now search for a user with a matching surname.
|
||||
//
|
||||
// Set up a search control so that the search is scoped to the sub-tree
|
||||
SearchControls controls = new SearchControls();
|
||||
controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
|
||||
|
||||
// Obtain the start search context - tbd - this will be removed once the functionality flows into Bandit
|
||||
String searchContext = m_svcConfig.getSetting(SvcConfig.StartSearchContext);
|
||||
if (searchContext == null)
|
||||
{
|
||||
// A start search context was not configured, start from the root.
|
||||
searchContext = "";
|
||||
}
|
||||
|
||||
// Perform the search
|
||||
NamingEnumeration answer = ctx.search(searchContext,
|
||||
"(cn={0})",
|
||||
new String[] {pwToken.getUsername()},
|
||||
controls);
|
||||
|
||||
// Enumerate through the users returned checking the password
|
||||
while (answer.hasMore())
|
||||
{
|
||||
SearchResult sr = (SearchResult)answer.next();
|
||||
|
||||
// Open a directory context for the user as a way of verifying its password
|
||||
try
|
||||
{
|
||||
Hashtable env2 = new Hashtable();
|
||||
env2.put(Context.INITIAL_CONTEXT_FACTORY, "org.bandit.ia.IAInitialCtxFactory");
|
||||
env2.put(IAContext.IA_REALM_CONFIG_LOCATION, m_svcConfig.getSetting(SvcConfig.IdentityAbstractionConfigFile));
|
||||
env2.put(IAContext.IA_REALM_SELECTOR, authReqMsg.getRealm());
|
||||
env2.put(Context.SECURITY_AUTHENTICATION, "simple");
|
||||
env2.put(Context.SECURITY_PRINCIPAL, sr.getName());
|
||||
env2.put(Context.SECURITY_CREDENTIALS, pwToken.getPassword());
|
||||
|
||||
if ((new InitialDirContext(env2)) != null)
|
||||
{
|
||||
// The password must be valid, set the identity Id.
|
||||
if (searchContext.equals(""))
|
||||
{
|
||||
identId = sr.getName();
|
||||
}
|
||||
else
|
||||
{
|
||||
identId = sr.getName() + "," + searchContext;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (NamingException e)
|
||||
{
|
||||
System.err.println("PwdAuthenticate.invoke()- NamingException: " + e.getExplanation());
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (NamingException e)
|
||||
{
|
||||
// Log the error
|
||||
System.err.println("PwdAuthenticate.invoke()- NamingException on Proxy User: " + e.getExplanation());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
System.err.println("PwdAuthenticate.invoke()- Exception: " + e.toString());
|
||||
}
|
||||
|
||||
// Return the authentication result
|
||||
return identId;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the mechanism id.
|
||||
*/
|
||||
public String getId()
|
||||
{
|
||||
return "PwdAuthenticate";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<settings>
|
||||
<description>This is the authentication mechanism for the PwdAuthenticate scheme. The PwdAuthenticate scheme authenticates entities using username/password tokens.</description>
|
||||
<ClassName>com.novell.casa.authtoksvc.PwdAuthenticate</ClassName>
|
||||
<RelativeClassPath>WEB-INF/classes</RelativeClassPath>
|
||||
</settings>
|
||||
@@ -0,0 +1,285 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail,
|
||||
* you may find current contact information at www.novell.com.
|
||||
*
|
||||
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
package com.novell.casa.authtoksvc;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.*;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
|
||||
/**
|
||||
* Rpc Servlet Class.
|
||||
*
|
||||
* This class processes Rpcs to the Authentication Token Service.
|
||||
*
|
||||
*/
|
||||
public class Rpc extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet
|
||||
{
|
||||
private static final long serialVersionUID = -8264027868130334613L;
|
||||
|
||||
private String m_appFolderPath = null;
|
||||
private String m_configFolderPath = null;
|
||||
|
||||
protected ReconfigureThread m_reconfigureThread = null;
|
||||
protected int m_reconfigureInterval; // seconds
|
||||
|
||||
private Map m_methodsMap;
|
||||
|
||||
/*
|
||||
* Reconfigure Thread Class.
|
||||
*
|
||||
* This class implements a runnable thread that reconfigures an Rpc Servlet instance.
|
||||
*
|
||||
*/
|
||||
private class ReconfigureThread implements Runnable
|
||||
{
|
||||
private Rpc m_rpc;
|
||||
private Thread m_thread;
|
||||
|
||||
/*
|
||||
* Constructor.
|
||||
*/
|
||||
public ReconfigureThread (Rpc rpc)
|
||||
{
|
||||
m_rpc = rpc;
|
||||
m_thread = new Thread(this);
|
||||
m_thread.start();
|
||||
}
|
||||
|
||||
/*
|
||||
* run() implementation.
|
||||
*/
|
||||
public void run ()
|
||||
{
|
||||
System.err.println("ReconfigureThread.run()- Running");
|
||||
|
||||
while (true)
|
||||
{
|
||||
// Sleep an ammount equal the reconfigure interval for the Rpc
|
||||
try
|
||||
{
|
||||
m_thread.sleep(m_rpc.m_reconfigureInterval * 1000);
|
||||
}
|
||||
catch (InterruptedException e) { /* nothing to do */ }
|
||||
|
||||
// Re-configure the Rpc servlet.
|
||||
try
|
||||
{
|
||||
m_rpc.configureServlet();
|
||||
|
||||
// Check if it is no longer necessary to re-configure the servlet
|
||||
if (m_rpc.m_reconfigureInterval == 0)
|
||||
{
|
||||
System.err.println("ReconfigureTask.run()- Configuration changed to no longer perform timed re-configuration");
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
System.err.println("ReconfigureTask.run()- Exception caught during re-configure process, " + e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* stop() implementation.
|
||||
*/
|
||||
public void stop ()
|
||||
{
|
||||
m_thread.stop();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor.
|
||||
*/
|
||||
public Rpc ()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
/*
|
||||
* configureServlet() implementation.
|
||||
*/
|
||||
protected void configureServlet () throws Exception
|
||||
{
|
||||
// Read service configuration
|
||||
SvcConfig svcConfig = new SvcConfig(m_appFolderPath, m_configFolderPath);
|
||||
|
||||
// Get the reconfigure interval
|
||||
try
|
||||
{
|
||||
m_reconfigureInterval = Integer.parseInt(svcConfig.getSetting(SvcConfig.ReconfigureInterval));
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
System.err.println("Rpc.configureServlet()- Invalid reconfigure interval value format");
|
||||
m_reconfigureInterval = Integer.parseInt(SvcConfig.DefaultReconfigureIntervalValue);
|
||||
}
|
||||
|
||||
// Read enabled services configuration
|
||||
EnabledSvcsConfig enabledSvcsConfig = new EnabledSvcsConfig(m_configFolderPath);
|
||||
|
||||
// Create a map to keep track of the Rpc methods
|
||||
Map methodsMap = new HashMap();
|
||||
|
||||
// Instantiate the Rpc Methods
|
||||
RpcMethod getAuthPolicy = new GetAuthPolicy();
|
||||
getAuthPolicy.init(svcConfig, enabledSvcsConfig);
|
||||
methodsMap.put(getAuthPolicy.getId(), getAuthPolicy);
|
||||
|
||||
RpcMethod authenticate = new Authenticate();
|
||||
authenticate.init(svcConfig, enabledSvcsConfig);
|
||||
methodsMap.put(authenticate.getId(), authenticate);
|
||||
|
||||
RpcMethod getAuthToken = new GetAuthToken();
|
||||
getAuthToken.init(svcConfig, enabledSvcsConfig);
|
||||
methodsMap.put(getAuthToken.getId(), getAuthToken);
|
||||
|
||||
// Set the map as the methods map used by the servlet
|
||||
m_methodsMap = methodsMap;
|
||||
}
|
||||
|
||||
/*
|
||||
* init() implementation.
|
||||
*/
|
||||
public void init (ServletConfig config) throws ServletException
|
||||
{
|
||||
super.init(config);
|
||||
|
||||
System.err.println("Rpc.init()");
|
||||
|
||||
try
|
||||
{
|
||||
// Get the path to our configuration folder
|
||||
//
|
||||
// First check if it has been specified via a system property
|
||||
ServletContext context = config.getServletContext();
|
||||
m_appFolderPath = context.getRealPath(File.separator);
|
||||
m_configFolderPath = System.getProperty("com.novell.casa.authtoksvc.config");
|
||||
if (m_configFolderPath == null)
|
||||
{
|
||||
// The path to the svc config folder was not specified via a system
|
||||
// property, assume that it's location is off the WEB-INF folder for
|
||||
// our web application.
|
||||
m_configFolderPath = m_appFolderPath + "WEB-INF/conf";
|
||||
}
|
||||
|
||||
// Configure ourselves
|
||||
configureServlet();
|
||||
|
||||
// Check if we must start a thread to periodically reconfigure ourselves
|
||||
if (m_reconfigureInterval != 0)
|
||||
{
|
||||
m_reconfigureThread = new ReconfigureThread(this);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
System.err.println("Rpc.init()- Exception caught: " + e.toString());
|
||||
throw new ServletException("Exception caught while instantiating Rpc methods");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* destroy() implementation.
|
||||
*/
|
||||
public void destroy ()
|
||||
{
|
||||
super.destroy();
|
||||
|
||||
System.err.println("Rpc.destroy()");
|
||||
|
||||
// Stop our re-configure thread
|
||||
if (m_reconfigureThread != null)
|
||||
{
|
||||
m_reconfigureThread.stop();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* doGet() implementation.
|
||||
*/
|
||||
protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
|
||||
{
|
||||
doPost(request, response);
|
||||
}
|
||||
|
||||
/*
|
||||
* doPost() implementation.
|
||||
*/
|
||||
protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
|
||||
{
|
||||
// Get ready to send back a reply
|
||||
response.setContentType("text/html");
|
||||
PrintWriter out = response.getWriter();
|
||||
|
||||
try
|
||||
{
|
||||
// Obtain the input stream and execute the requested method
|
||||
InputStream inStream = request.getInputStream();
|
||||
|
||||
String requestedMethod = request.getParameter("method");
|
||||
if (requestedMethod != null)
|
||||
{
|
||||
// Get the necessary method
|
||||
RpcMethod method = (RpcMethod) m_methodsMap.get(requestedMethod);
|
||||
if (method != null)
|
||||
{
|
||||
// Invoke the method to process the Rpc
|
||||
method.invoke(inStream, out);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unsupported method
|
||||
System.err.println("Rpc.doPost()- Unsupported method");
|
||||
response.sendError(response.SC_BAD_REQUEST);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Missing method parameter
|
||||
System.err.println("Rpc.doPost()- Missing method parameter");
|
||||
response.sendError(response.SC_BAD_REQUEST);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// tbd
|
||||
System.err.println("Rpc.doPost()- Exception caught: " + e.toString());
|
||||
response.sendError(response.SC_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
// Done sending out the reply
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user