From c5954540eb3b4cdcd3b9868b2d34be56a9456e00 Mon Sep 17 00:00:00 2001 From: Juan Carlos Luciani Date: Mon, 7 Aug 2006 19:12:49 +0000 Subject: [PATCH] Adding client files lost during folder re-structuring. --- CASA-auth-token/non-java/client/README | 67 ++ CASA-auth-token/non-java/client/TODO | 18 + CASA-auth-token/non-java/client/authmech.c | 339 ++++++++ CASA-auth-token/non-java/client/authmsg.c | 803 ++++++++++++++++++ CASA-auth-token/non-java/client/authpolicy.c | 801 +++++++++++++++++ .../authtokenclient_msi.vdproj | 694 +++++++++++++++ .../authtokenclient_msm.vdproj | 438 ++++++++++ CASA-auth-token/non-java/client/client.vcproj | 221 +++++ CASA-auth-token/non-java/client/config.c | 685 +++++++++++++++ CASA-auth-token/non-java/client/config_if.h | 120 +++ CASA-auth-token/non-java/client/engine.c | 696 +++++++++++++++ .../non-java/client/getpolicymsg.c | 745 ++++++++++++++++ CASA-auth-token/non-java/client/gettokenmsg.c | 793 +++++++++++++++++ CASA-auth-token/non-java/client/internal.h | 395 +++++++++ CASA-auth-token/non-java/client/mech_if.h | 177 ++++ .../mechanisms/krb5/Krb5Authenticate.conf | 12 + .../non-java/client/mechanisms/krb5/README | 30 + .../non-java/client/mechanisms/krb5/TODO | 14 + .../client/mechanisms/krb5/interface.c | 207 +++++ .../client/mechanisms/krb5/internal.h | 90 ++ .../client/mechanisms/krb5/krb5.vcproj | 182 ++++ .../non-java/client/mechanisms/krb5/util.c | 282 ++++++ .../client/mechanisms/krb5/windows/dllsup.c | 132 +++ .../client/mechanisms/krb5/windows/get.c | 272 ++++++ .../mechanisms/krb5/windows/krb5mech.def | 10 + .../client/mechanisms/krb5/windows/platform.c | 35 + .../client/mechanisms/krb5/windows/platform.h | 83 ++ .../mechanisms/pwd/PwdAuthenticate.conf | 12 + .../non-java/client/mechanisms/pwd/README | 27 + .../non-java/client/mechanisms/pwd/TODO | 14 + .../non-java/client/mechanisms/pwd/get.c | 359 ++++++++ .../client/mechanisms/pwd/interface.c | 207 +++++ .../non-java/client/mechanisms/pwd/internal.h | 92 ++ .../non-java/client/mechanisms/pwd/pwd.vcproj | 183 ++++ .../non-java/client/mechanisms/pwd/util.c | 282 ++++++ .../client/mechanisms/pwd/windows/dllsup.c | 132 +++ .../client/mechanisms/pwd/windows/platform.c | 35 + .../client/mechanisms/pwd/windows/platform.h | 81 ++ .../client/mechanisms/pwd/windows/pwmech.def | 10 + .../non-java/client/test/CASA_Auth.cpp | 513 +++++++++++ .../non-java/client/test/test.vcproj | 142 ++++ CASA-auth-token/non-java/client/util.c | 321 +++++++ .../non-java/client/windows/authtoken.def | 10 + .../non-java/client/windows/dllsup.c | 132 +++ .../non-java/client/windows/platform.c | 665 +++++++++++++++ .../non-java/client/windows/platform.h | 114 +++ CASA-auth-token/non-java/client/windows/rpc.c | 498 +++++++++++ 47 files changed, 12170 insertions(+) create mode 100644 CASA-auth-token/non-java/client/README create mode 100644 CASA-auth-token/non-java/client/TODO create mode 100644 CASA-auth-token/non-java/client/authmech.c create mode 100644 CASA-auth-token/non-java/client/authmsg.c create mode 100644 CASA-auth-token/non-java/client/authpolicy.c create mode 100644 CASA-auth-token/non-java/client/authtokenclient_msi/authtokenclient_msi.vdproj create mode 100644 CASA-auth-token/non-java/client/authtokenclient_msm/authtokenclient_msm.vdproj create mode 100644 CASA-auth-token/non-java/client/client.vcproj create mode 100644 CASA-auth-token/non-java/client/config.c create mode 100644 CASA-auth-token/non-java/client/config_if.h create mode 100644 CASA-auth-token/non-java/client/engine.c create mode 100644 CASA-auth-token/non-java/client/getpolicymsg.c create mode 100644 CASA-auth-token/non-java/client/gettokenmsg.c create mode 100644 CASA-auth-token/non-java/client/internal.h create mode 100644 CASA-auth-token/non-java/client/mech_if.h create mode 100644 CASA-auth-token/non-java/client/mechanisms/krb5/Krb5Authenticate.conf create mode 100644 CASA-auth-token/non-java/client/mechanisms/krb5/README create mode 100644 CASA-auth-token/non-java/client/mechanisms/krb5/TODO create mode 100644 CASA-auth-token/non-java/client/mechanisms/krb5/interface.c create mode 100644 CASA-auth-token/non-java/client/mechanisms/krb5/internal.h create mode 100644 CASA-auth-token/non-java/client/mechanisms/krb5/krb5.vcproj create mode 100644 CASA-auth-token/non-java/client/mechanisms/krb5/util.c create mode 100644 CASA-auth-token/non-java/client/mechanisms/krb5/windows/dllsup.c create mode 100644 CASA-auth-token/non-java/client/mechanisms/krb5/windows/get.c create mode 100644 CASA-auth-token/non-java/client/mechanisms/krb5/windows/krb5mech.def create mode 100644 CASA-auth-token/non-java/client/mechanisms/krb5/windows/platform.c create mode 100644 CASA-auth-token/non-java/client/mechanisms/krb5/windows/platform.h create mode 100644 CASA-auth-token/non-java/client/mechanisms/pwd/PwdAuthenticate.conf create mode 100644 CASA-auth-token/non-java/client/mechanisms/pwd/README create mode 100644 CASA-auth-token/non-java/client/mechanisms/pwd/TODO create mode 100644 CASA-auth-token/non-java/client/mechanisms/pwd/get.c create mode 100644 CASA-auth-token/non-java/client/mechanisms/pwd/interface.c create mode 100644 CASA-auth-token/non-java/client/mechanisms/pwd/internal.h create mode 100644 CASA-auth-token/non-java/client/mechanisms/pwd/pwd.vcproj create mode 100644 CASA-auth-token/non-java/client/mechanisms/pwd/util.c create mode 100644 CASA-auth-token/non-java/client/mechanisms/pwd/windows/dllsup.c create mode 100644 CASA-auth-token/non-java/client/mechanisms/pwd/windows/platform.c create mode 100644 CASA-auth-token/non-java/client/mechanisms/pwd/windows/platform.h create mode 100644 CASA-auth-token/non-java/client/mechanisms/pwd/windows/pwmech.def create mode 100644 CASA-auth-token/non-java/client/test/CASA_Auth.cpp create mode 100644 CASA-auth-token/non-java/client/test/test.vcproj create mode 100644 CASA-auth-token/non-java/client/util.c create mode 100644 CASA-auth-token/non-java/client/windows/authtoken.def create mode 100644 CASA-auth-token/non-java/client/windows/dllsup.c create mode 100644 CASA-auth-token/non-java/client/windows/platform.c create mode 100644 CASA-auth-token/non-java/client/windows/platform.h create mode 100644 CASA-auth-token/non-java/client/windows/rpc.c diff --git a/CASA-auth-token/non-java/client/README b/CASA-auth-token/non-java/client/README new file mode 100644 index 00000000..66ed0620 --- /dev/null +++ b/CASA-auth-token/non-java/client/README @@ -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. + + + + + + + + + + diff --git a/CASA-auth-token/non-java/client/TODO b/CASA-auth-token/non-java/client/TODO new file mode 100644 index 00000000..a96f51d3 --- /dev/null +++ b/CASA-auth-token/non-java/client/TODO @@ -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. + diff --git a/CASA-auth-token/non-java/client/authmech.c b/CASA-auth-token/non-java/client/authmech.c new file mode 100644 index 00000000..991a64bb --- /dev/null +++ b/CASA-auth-token/non-java/client/authmech.c @@ -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 + * + ***********************************************************************/ + + +//===[ 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; +} + + +//++======================================================================= +//++======================================================================= +//++======================================================================= + diff --git a/CASA-auth-token/non-java/client/authmsg.c b/CASA-auth-token/non-java/client/authmsg.c new file mode 100644 index 00000000..96329276 --- /dev/null +++ b/CASA-auth-token/non-java/client/authmsg.c @@ -0,0 +1,803 @@ +/*********************************************************************** + * + * Copyright (C) 2006 Novell, Inc. All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, Novell, Inc. + * + * To contact Novell about this file by physical or electronic mail, + * you may find current contact information at www.novell.com. + * + * Author: Juan Carlos Luciani + * + ***********************************************************************/ + + +//===[ Include files ]===================================================== + +#include "internal.h" + +//===[ Type definitions ]================================================== + +// +// Parse states +// +#define AWAITING_ROOT_ELEMENT_START 0x0 +#define AWAITING_ROOT_ELEMENT_END 0x1 +#define AWAITING_STATUS_ELEMENT_START 0x2 +#define AWAITING_STATUS_ELEMENT_END 0x3 +#define AWAITING_STATUS_DATA 0x4 +#define AWAITING_DESCRIPTION_ELEMENT_START 0x5 +#define AWAITING_DESCRIPTION_ELEMENT_END 0x6 +#define AWAITING_DESCRIPTION_DATA 0x7 +#define AWAITING_SESSION_TOKEN_ELEMENT_START 0x8 +#define AWAITING_SESSION_TOKEN_ELEMENT_END 0x9 +#define AWAITING_SESSION_TOKEN_DATA 0xA +#define AWAITING_LIFETIME_DATA 0xB +#define AWAITING_LIFETIME_ELEMENT_START 0xC +#define AWAITING_LIFETIME_ELEMENT_END 0xD +#define AWAITING_AUTH_TOKEN_ELEMENT_START 0xE +#define AWAITING_AUTH_TOKEN_ELEMENT_END 0xF +#define AWAITING_AUTH_TOKEN_DATA 0x10 +#define AWAITING_REALM_DATA 0x12 +#define AWAITING_REALM_ELEMENT_END 0x13 +#define DONE_PARSING 0x14 + +// +// Authentication Response Parse Structure +// +typedef struct _AuthRespParse +{ + XML_Parser p; + int state; + int elementDataProcessed; + AuthenticateResp *pAuthenticateResp; + CasaStatus status; + +} AuthRespParse, *PAuthRespParse; + + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + +//++======================================================================= +char* +BuildAuthenticateMsg( + IN AuthContext *pAuthContext, + IN char *pAuthMechToken) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + char *pMsg = NULL; + int bufferSize; + + DbgTrace(1, "-BuildAuthenticateMsg- Start\n", 0); + + /* + * The format of the authentication request message is as follows: + * + * + * + * realm value + * mechanism id value + * authentication mechanism token data + * + * + */ + + // Determine the buffer size necessary to hold the msg + bufferSize = strlen(XML_DECLARATION) + + 2 // crlf + + 1 // < + + strlen(AUTH_REQUEST_ELEMENT_NAME) + + 3 // >crlf + + 1 // < + + strlen(REALM_ELEMENT_NAME) + + 1 // > + + strlen(pAuthContext->pContext) + + 2 // crlf + + 1 // < + + strlen(MECHANISM_ELEMENT_NAME) + + 1 // > + + strlen(pAuthContext->pMechanism) + + 2 // crlf + + 1 // < + + strlen(AUTH_MECH_TOKEN_ELEMENT_NAME) + + 1 // > + + strlen(pAuthMechToken) + + 2 // crlf + + 2 // null + + // Allocate the msg buffer + pMsg = (char*) malloc(bufferSize); + if (pMsg) + { + // Now build the message + memset(pMsg, 0, bufferSize); + strcat(pMsg, XML_DECLARATION); + strcat(pMsg, "\r\n"); + strcat(pMsg, "<"); + strcat(pMsg, AUTH_REQUEST_ELEMENT_NAME); + strcat(pMsg, ">\r\n"); + strcat(pMsg, "<"); + strcat(pMsg, REALM_ELEMENT_NAME); + strcat(pMsg, ">"); + strcat(pMsg, pAuthContext->pContext); + strcat(pMsg, "\r\n"); + strcat(pMsg, "<"); + strcat(pMsg, MECHANISM_ELEMENT_NAME); + strcat(pMsg, ">"); + strcat(pMsg, pAuthContext->pMechanism); + strcat(pMsg, "\r\n"); + strcat(pMsg, "<"); + strcat(pMsg, AUTH_MECH_TOKEN_ELEMENT_NAME); + strcat(pMsg, ">"); + strcat(pMsg, pAuthMechToken); + strcat(pMsg, "\r\n"); + strcat(pMsg, ""); + } + else + { + DbgTrace(0, "-BuildAuthenticateMsg- Buffer allocation error\n", 0); + } + + DbgTrace(1, "-BuildAuthenticateMsg- End, pMsg = %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: + * + * + * + * ok200 + * lifetime valuesession token data + * + * + * When an authentication request fails to be successfully processed, the server + * responds with an error and an error description string. The message format of + * an unsuccessful reply is as follows: + * + * + * + * status descriptionstatus code + * + * + * Plase note that the protocol utilizes the status codes defined + * in the HTTP 1.1 Specification. + * + */ + + // Allocate AuthenticateResp object + pAuthenticateResp = malloc(sizeof(*pAuthenticateResp)); + if (pAuthenticateResp) + { + XML_Parser p; + + // Initialize the AuthenticateResp object and set it in the + // authentication response parse oject. + memset(pAuthenticateResp, 0, sizeof(*pAuthenticateResp)); + authRespParse.pAuthenticateResp = pAuthenticateResp; + + // Create parser + p = XML_ParserCreate(NULL); + if (p) + { + // Keep track of the parser in our parse object + authRespParse.p = p; + + // Initialize the status within the parse object + authRespParse.status = CASA_STATUS_SUCCESS; + + // Set the start and end element handlers + XML_SetElementHandler(p, + 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); +} + + +//++======================================================================= +//++======================================================================= +//++======================================================================= + diff --git a/CASA-auth-token/non-java/client/authpolicy.c b/CASA-auth-token/non-java/client/authpolicy.c new file mode 100644 index 00000000..b69ce2b0 --- /dev/null +++ b/CASA-auth-token/non-java/client/authpolicy.c @@ -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 + * + ***********************************************************************/ + + +//===[ 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: + * + * + * + * + * realm name + * authentication mechanism type + * authentication mechanism context data + * + * ... + * + * + * The authentication policy document can contain multiple auth_source + * elements. These auth_source elements can be for different authentication + * sources or for the same authentication source but specifying a different + * authentication mechanism. + * + * The following is a sample authentication policy document: + * + * + * + * + * Corp_eDirTree + * Krb5Authenticate + * host/hostname + * + * + * Corp_eDirTree + * PwdAuthenticate + * + * + * + * + * This authentication policy would tell the CASA client that it can + * authenticate to the CASA Authentication Token Service using + * credentials for the Corp_eDirTree and utilizing either the + * Krb5 authentication mechanism or the Pwd authentication mechanism. + * The Krb5 authentication mechanism context data specifies the + * name of the Kerberos service principal. + * + */ + + // Initialize output parameter + *ppAuthPolicy = NULL; + + // Decode the data + retStatus = DecodeData(pEncodedData, + encodedDataLen, + &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); +} + + +//++======================================================================= +//++======================================================================= +//++======================================================================= + diff --git a/CASA-auth-token/non-java/client/authtokenclient_msi/authtokenclient_msi.vdproj b/CASA-auth-token/non-java/client/authtokenclient_msi/authtokenclient_msi.vdproj new file mode 100644 index 00000000..07135092 --- /dev/null +++ b/CASA-auth-token/non-java/client/authtokenclient_msi/authtokenclient_msi.vdproj @@ -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:\\VsdUserInterface.wim" + } + "{8D9DEE8B-DD8B-4F48-9072-C4364E4F4011}:_2873941BB49A4737AF72ED5E788318F7" + { + "Name" = "8:#1902" + "Sequence" = "3:1" + "Attributes" = "3:3" + "Dialogs" + { + "{18ADD6EC-89FE-4ED7-AD3E-211C40278470}:_10695426506044F6B667E02B3E33A00E" + { + "Sequence" = "3:100" + "DisplayName" = "8:Finished" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdFinishedDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "UpdateText" + { + "Name" = "8:UpdateText" + "DisplayName" = "8:#1058" + "Description" = "8:#1158" + "Type" = "3:15" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1258" + "DefaultValue" = "8:#1258" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{8D9DEE8B-DD8B-4F48-9072-C4364E4F4011}:_353966B93CCA47F89005110A192B33E0" + { + "Name" = "8:#1900" + "Sequence" = "3:2" + "Attributes" = "3:1" + "Dialogs" + { + "{18ADD6EC-89FE-4ED7-AD3E-211C40278470}:_A41DEF6D91134F42BA300A817856F7C2" + { + "Sequence" = "3:300" + "DisplayName" = "8:Confirm Installation" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdAdminConfirmDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{18ADD6EC-89FE-4ED7-AD3E-211C40278470}:_D915672F6CE04B29A5482A7E9297CE42" + { + "Sequence" = "3:100" + "DisplayName" = "8:Welcome" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdAdminWelcomeDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "CopyrightWarning" + { + "Name" = "8:CopyrightWarning" + "DisplayName" = "8:#1002" + "Description" = "8:#1102" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1202" + "DefaultValue" = "8:#1202" + "UsePlugInResources" = "11:TRUE" + } + "Welcome" + { + "Name" = "8:Welcome" + "DisplayName" = "8:#1003" + "Description" = "8:#1103" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1203" + "DefaultValue" = "8:#1203" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{18ADD6EC-89FE-4ED7-AD3E-211C40278470}:_E8BB0C75759A4ECA9292D5EB62A4B1DD" + { + "Sequence" = "3:200" + "DisplayName" = "8:Installation Folder" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdAdminFolderDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{8D9DEE8B-DD8B-4F48-9072-C4364E4F4011}:_72EFC743AB3B42B6994F5EC55E41631F" + { + "Name" = "8:#1901" + "Sequence" = "3:1" + "Attributes" = "3:2" + "Dialogs" + { + "{18ADD6EC-89FE-4ED7-AD3E-211C40278470}:_9D455462808342AE837694F103194C3E" + { + "Sequence" = "3:100" + "DisplayName" = "8:Progress" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdProgressDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "ShowProgress" + { + "Name" = "8:ShowProgress" + "DisplayName" = "8:#1009" + "Description" = "8:#1109" + "Type" = "3:5" + "ContextData" = "8:1;True=1;False=0" + "Attributes" = "3:0" + "Setting" = "3:0" + "Value" = "3:1" + "DefaultValue" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{B654A020-6903-4E6A-A86C-75DC463DB54B}:_A0A8360C0E0D46ACB472E47806B666D5" + { + "UseDynamicProperties" = "11:FALSE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdBasicDialogs.wim" + } + "{8D9DEE8B-DD8B-4F48-9072-C4364E4F4011}:_D708D6BFB2C946BB9BCCC9F6F2CAE0FA" + { + "Name" = "8:#1902" + "Sequence" = "3:2" + "Attributes" = "3:3" + "Dialogs" + { + "{18ADD6EC-89FE-4ED7-AD3E-211C40278470}:_964E18CF17534E789061E20F26EE5EDA" + { + "Sequence" = "3:100" + "DisplayName" = "8:Finished" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdAdminFinishedDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{8D9DEE8B-DD8B-4F48-9072-C4364E4F4011}:_E294259CC9424A6EB901523FCAD0D0CC" + { + "Name" = "8:#1900" + "Sequence" = "3:1" + "Attributes" = "3:1" + "Dialogs" + { + "{18ADD6EC-89FE-4ED7-AD3E-211C40278470}:_7F0506CDE05C426E9A69E1F0F6A1B9A4" + { + "Sequence" = "3:200" + "DisplayName" = "8:Installation Folder" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\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:\\VsdConfirmDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{18ADD6EC-89FE-4ED7-AD3E-211C40278470}:_EF6CBFADEBBA4F4BA427709FD0C72385" + { + "Sequence" = "3:100" + "DisplayName" = "8:Welcome" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdWelcomeDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "CopyrightWarning" + { + "Name" = "8:CopyrightWarning" + "DisplayName" = "8:#1002" + "Description" = "8:#1102" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1202" + "DefaultValue" = "8:#1202" + "UsePlugInResources" = "11:TRUE" + } + "Welcome" + { + "Name" = "8:Welcome" + "DisplayName" = "8:#1003" + "Description" = "8:#1103" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1203" + "DefaultValue" = "8:#1203" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{8D9DEE8B-DD8B-4F48-9072-C4364E4F4011}:_FC54039B5B444B8C8D7C64B693C25B14" + { + "Name" = "8:#1901" + "Sequence" = "3:2" + "Attributes" = "3:2" + "Dialogs" + { + "{18ADD6EC-89FE-4ED7-AD3E-211C40278470}:_E79C486A92E54E4881FBD841C4649B83" + { + "Sequence" = "3:100" + "DisplayName" = "8:Progress" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdAdminProgressDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "ShowProgress" + { + "Name" = "8:ShowProgress" + "DisplayName" = "8:#1009" + "Description" = "8:#1109" + "Type" = "3:5" + "ContextData" = "8:1;True=1;False=0" + "Attributes" = "3:0" + "Setting" = "3:0" + "Value" = "3:1" + "DefaultValue" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + } + "MergeModule" + { + } + "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" + { + } + } +} diff --git a/CASA-auth-token/non-java/client/authtokenclient_msm/authtokenclient_msm.vdproj b/CASA-auth-token/non-java/client/authtokenclient_msm/authtokenclient_msm.vdproj new file mode 100644 index 00000000..420a9086 --- /dev/null +++ b/CASA-auth-token/non-java/client/authtokenclient_msm/authtokenclient_msm.vdproj @@ -0,0 +1,438 @@ +"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:_1ED6B3F7C91A4BBE875FC4621FC3CD97" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_677B016062384F4C8A73EC952CBCFD76" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_9A2FC85FE99C48E8AD1E4813BE33A03A" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_DB9D7F0710B44F858325E4EFCCB2EEB3" + "OwnerKey" = "8:_UNDEFINED" + "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}:_1ED6B3F7C91A4BBE875FC4621FC3CD97" + { + "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}:_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:" + } + } + "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\\krb5\\windows\\Debug\\krb5mech.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_F5F5F604B81645F8B6463F7A7D6A53AD" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + "ProjectOutputGroupRegister" = "3:1" + "OutputConfiguration" = "8:" + "OutputGroupCanonicalName" = "8:Built" + "OutputProjectGuid" = "8:{5499F624-F371-4559-B4C2-A484BCE892FD}" + "ShowKeyOutput" = "11:FALSE" + "ExcludeFilters" + { + } + } + "{8062640A-2EEE-46E9-AB67-688E9A886E9F}:_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" + { + } + } +} diff --git a/CASA-auth-token/non-java/client/client.vcproj b/CASA-auth-token/non-java/client/client.vcproj new file mode 100644 index 00000000..ad9dbe87 --- /dev/null +++ b/CASA-auth-token/non-java/client/client.vcproj @@ -0,0 +1,221 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CASA-auth-token/non-java/client/config.c b/CASA-auth-token/non-java/client/config.c new file mode 100644 index 00000000..fa6c601b --- /dev/null +++ b/CASA-auth-token/non-java/client/config.c @@ -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 + * + ***********************************************************************/ + + +//===[ 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; +} + + +//++======================================================================= +//++======================================================================= +//++======================================================================= + diff --git a/CASA-auth-token/non-java/client/config_if.h b/CASA-auth-token/non-java/client/config_if.h new file mode 100644 index 00000000..0cdf31ce --- /dev/null +++ b/CASA-auth-token/non-java/client/config_if.h @@ -0,0 +1,120 @@ +/*********************************************************************** + * + * Copyright (C) 2006 Novell, Inc. All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, Novell, Inc. + * + * To contact Novell about this file by physical or electronic mail, + * you may find current contact information at www.novell.com. + * + * Author: Juan Carlos Luciani + * + ***********************************************************************/ + + +#ifndef _CONFIG_IF_H_ +#define _CONFIG_IF_H_ + + +//===[ Include files ]===================================================== + +//===[ Type definitions ]================================================== + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + +/************************************************************************** +*************************************************************************** +** ** +** Configuration Object Interface Definitions ** +** ** +*************************************************************************** +**************************************************************************/ + + +//++======================================================================= +typedef +int +(SSCS_CALL *PFNConfiglIf_AddReference)( + IN const void *pIfInstance); +// +// Arguments: +// pIfInstance - +// Pointer to interface object. +// +// Returns: +// Interface reference count. +// +// Description: +// Increases interface reference count. +//=======================================================================-- + + +//++======================================================================= +typedef +void +(SSCS_CALL *PFNConfiglIf_ReleaseReference)( + IN const void *pIfInstance); +// +// Arguments: +// pIfInstance - +// Pointer to interface object. +// +// Returns: +// Nothing. +// +// Description: +// Decreases interface reference count. The interface is deallocated if +// the reference count becomes zero. +//=======================================================================-- + + +//++======================================================================= +typedef +char* +(SSCS_CALL *PFNConfiglIf_GetEntryValue)( + IN const void *pIfInstance, + IN const char *pKeyName); +// +// Arguments: +// pIfInstance - +// Pointer to interface object. +// +// pKeyName - +// Pointer to NULL terminated string that contains the +// name of the key whose value is being requested. +// +// Returns: +// Pointer to NULL terminated string with value being requested or NULL. +// +// Description: +// Gets value associated with a key for the configuration object. +//=======================================================================-- + + +// +// Config Interface Object +// +typedef struct _ConfigIf +{ + PFNConfiglIf_AddReference addReference; + PFNConfiglIf_ReleaseReference releaseReference; + PFNConfiglIf_GetEntryValue getEntryValue; + +} ConfigIf, *PConfigIf; + + +#endif // #ifndef _CONFIG_IF_H_ + diff --git a/CASA-auth-token/non-java/client/engine.c b/CASA-auth-token/non-java/client/engine.c new file mode 100644 index 00000000..8ecfc68f --- /dev/null +++ b/CASA-auth-token/non-java/client/engine.c @@ -0,0 +1,696 @@ +/*********************************************************************** + * + * Copyright (C) 2006 Novell, Inc. All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, Novell, Inc. + * + * To contact Novell about this file by physical or electronic mail, + * you may find current contact information at www.novell.com. + * + * Author: Juan Carlos Luciani + * + ***********************************************************************/ + + +//===[ Include files ]===================================================== + +#include "internal.h" + +//===[ Type definitions ]================================================== + +#define DEFAULT_RETRY_LIFETIME 5 // seconds + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + +// +// Debug tracing level +// +int DebugLevel = 0; + +// +// Operating parameter +// +bool secureRpcSetting = false; +bool g_bInitialized = FALSE; + +//++======================================================================= +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 + { + // Free the entry + FreeAuthCacheEntry(pCacheEntry); + } + } + + // Advance to the next entry + pListEntry = pListEntry->Flink; + } + + // If we did not find a cache entry that we can use, then try to create one. + pListEntry = pAuthPolicy->authContextListHead.Flink; + while (!CASA_SUCCESS(retStatus) + && pListEntry != &pAuthPolicy->authContextListHead) + { + AuthContext *pAuthContext; + char *pAuthMechToken; + + // Get pointer to AuthContext structure + pAuthContext = CONTAINING_RECORD(pListEntry, AuthContext, listEntry); + + // Only try to create cache entry for the auth context if there is not + // one already. + pCacheEntry = FindSessionTokenEntryInCache(pAuthContext->pContext); + if (pCacheEntry == NULL) + { + char *pReqMsg = NULL; + char *pRespMsg = NULL; + int respLen; + + // 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; + } + + // 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 = CreateSessionTokenCacheEntry( + pAuthContext->pContext, + retStatus, + pAuthenticateResp->pToken, + pAuthenticateResp->tokenLifetime); + + pAuthenticateResp->pToken = NULL; // To keep us from freeing the buffer + + // Free the Authenticate response object + RelAuthenticateResp(pAuthenticateResp); + } + } + else + { + DbgTrace(0, "-ObtainSessionToken- Authenticate Rpc failure, error = %08X\n", retStatus); + } + + // Free resources that may be hanging around + if (pRespMsg) + free(pRespMsg); + + free(pReqMsg); + } + else + { + DbgTrace(0, "-ObtainSessionToken- Error building Authenticate msg\n", 0); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + + // Add the entry to the cache if successful or if the reason that we failed + // was because the server was unavailable. + if (CasaStatusCode(retStatus) == CASA_STATUS_AUTH_SERVER_UNAVAILABLE) + { + pCacheEntry = CreateSessionTokenCacheEntry( + pAuthContext->pContext, + retStatus, + NULL, + DEFAULT_RETRY_LIFETIME); + + } + + // Release the cache entry if the resulting status is not successful + if (!CASA_SUCCESS(retStatus)) + { + FreeAuthCacheEntry(pCacheEntry); + } + + // Free up the buffer associated with the authentication mechanism token + free(pAuthMechToken); + } + else + { + // Free the entry + FreeAuthCacheEntry(pCacheEntry); + } + + // Advance to the next entry + pListEntry = pListEntry->Flink; + } + + // Return session token if successful + if (CASA_SUCCESS(retStatus)) + { + // Allocate a buffer for the return token + *ppSessionToken = (char*) malloc(strlen(pCacheEntry->token) + 1); + if (*ppSessionToken) + { + // Copy the token onto the allocated buffer + strcpy(*ppSessionToken, pCacheEntry->token); + } + else + { + DbgTrace(0, "-ObtainSessionToken- Buffer allocation failure\n", 0); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + + FreeAuthCacheEntry(pCacheEntry); + } + + DbgTrace(1, "-ObtainSessionToken- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +static +CasaStatus +ObtainAuthTokenFromServer( + IN const char *pServiceName, + IN const char *pHostName, + INOUT char **ppAuthToken, + INOUT int *pTokenLifetime) +// +// 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; + unsigned char *pToken; + HANDLE hUserMutex = NULL; + + + 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; + } + + // Make sure we are initialized + // Obtain our synchronization mutex + AcquireInitializationMutex(); + + // Create user synchronization mutex + retStatus = CreateUserMutex(&hUserMutex); + + if (retStatus != CASA_STATUS_SUCCESS) + { + DbgTrace(0, "-ObtainAuthToken- Error creating mutex for the user\n", 0); + goto exit; + } + + if (g_bInitialized == FALSE) + { + retStatus = InitializeLibrary(); + + if (retStatus == CASA_STATUS_SUCCESS) + { + g_bInitialized = TRUE; + } + else + { + goto exit; + } + } + + // Release our synchronization mutex + ReleaseInitializationMutex(); + + // Normalize the host name + pNormalizedHostName = NormalizeHostName(pHostName); + if (pNormalizedHostName) + { + // Start user process synchronization + AcquireUserMutex(hUserMutex); + + // Try to find a cache entry for the service + pCacheEntry = FindAuthTokenEntryInCache(pServiceName, pNormalizedHostName); + if (pCacheEntry == NULL) + { + // Initialize to retry in case of failure + int cacheEntryLifetime = DEFAULT_RETRY_LIFETIME; + + // Cache entry created, now try to obtain auth token from the CASA Server + retStatus = ObtainAuthTokenFromServer(pServiceName, + pNormalizedHostName, + &pToken, + &cacheEntryLifetime); + + // Add the entry to the cache if successful or if the reason that we failed + // was because the server was un-available. + if (CASA_SUCCESS(retStatus) + || CasaStatusCode(retStatus) == CASA_STATUS_AUTH_SERVER_UNAVAILABLE) + { + pCacheEntry = CreateAuthTokenCacheEntry( + pServiceName, + pNormalizedHostName, + retStatus, + pToken, + cacheEntryLifetime); + + if (pCacheEntry) + { + // Release the cache entry if the resulting status is not successful + if (!CASA_SUCCESS(retStatus)) + { + FreeAuthCacheEntry(pCacheEntry); + } + } + } + + } + else + { + // Cache entry found, update the return status with the information saved in it + // and release it if its status is not successful. + if (!CASA_SUCCESS(retStatus = pCacheEntry->status)) + { + FreeAuthCacheEntry(pCacheEntry); + } + } + + + // Try to return auth token if we have one to return + if (CASA_SUCCESS(retStatus)) + { + int tokenLen = (int) strlen(pCacheEntry->token) + 1; + + // We have an authentication token, try to return it to the caller + // after verifying that the supplied buffer is big enough. + if (*pAuthTokenBufLen >= tokenLen) + { + // Return the auth token to the caller + strcpy(pAuthTokenBuf, pCacheEntry->token); + } + 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; + + FreeAuthCacheEntry(pCacheEntry); + } + + // Stop user process synchronization + ReleaseUserMutex(hUserMutex); + + // 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: + + if (hUserMutex != NULL) + { + DestroyUserMutex(hUserMutex); + } + + DbgTrace(1, "-ObtainAuthToken- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +int +Initialize(void) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + int retStatus; + + DbgTrace(1, "-InitializeLibrary- Start\n", 0); + + retStatus = CreateInitializationMutex(); + + DbgTrace(1, "-InitializeLibrary- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +int +InitializeLibrary(void) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + int retStatus = -1; + + DbgTrace(1, "-InitializeLibrary- Start\n", 0); + + // Initialize the host name normalization + retStatus = InitializeHostNameNormalization(); + + + if (CASA_SUCCESS(retStatus)) + { + retStatus = InitializeAuthCache(); + } + + + DbgTrace(1, "-InitializeLibrary- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + +//++======================================================================= +//++======================================================================= +//++======================================================================= + diff --git a/CASA-auth-token/non-java/client/getpolicymsg.c b/CASA-auth-token/non-java/client/getpolicymsg.c new file mode 100644 index 00000000..5b568cc8 --- /dev/null +++ b/CASA-auth-token/non-java/client/getpolicymsg.c @@ -0,0 +1,745 @@ +/*********************************************************************** + * + * Copyright (C) 2006 Novell, Inc. All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, Novell, Inc. + * + * To contact Novell about this file by physical or electronic mail, + * you may find current contact information at www.novell.com. + * + * Author: Juan Carlos Luciani + * + ***********************************************************************/ + + +//===[ Include files ]===================================================== + +#include "internal.h" + +//===[ Type definitions ]================================================== + +// +// Parse states +// +#define AWAITING_ROOT_ELEMENT_START 0x0 +#define AWAITING_ROOT_ELEMENT_END 0x1 +#define AWAITING_STATUS_ELEMENT_START 0x2 +#define AWAITING_STATUS_ELEMENT_END 0x3 +#define AWAITING_STATUS_DATA 0x4 +#define AWAITING_DESCRIPTION_ELEMENT_START 0x5 +#define AWAITING_DESCRIPTION_ELEMENT_END 0x6 +#define AWAITING_DESCRIPTION_DATA 0x7 +#define AWAITING_AUTH_TOKEN_ELEMENT_START 0x8 +#define AWAITING_AUTH_TOKEN_ELEMENT_END 0x9 +#define AWAITING_AUTH_TOKEN_DATA 0xA +#define AWAITING_AUTH_POLICY_ELEMENT_START 0xB +#define AWAITING_AUTH_POLICY_ELEMENT_END 0xC +#define AWAITING_AUTH_POLICY_DATA 0xD +#define DONE_PARSING 0xE + +// +// Get Authentication Policy Response Parse Structure +// +typedef struct _GetAuthPolicyRespParse +{ + XML_Parser p; + int state; + int elementDataProcessed; + GetAuthPolicyResp *pGetAuthPolicyResp; + CasaStatus status; + +} GetAuthPolicyRespParse, *PGetAuthPolicyRespParse; + + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + + +//++======================================================================= +char* +BuildGetAuthPolicyMsg( + IN 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: + * + * + * + * service name<\service> + * host name + * + * + */ + + // Determine the buffer size necessary to hold the msg + bufferSize = strlen(XML_DECLARATION) + + 2 // crlf + + 1 // < + + strlen(GET_AUTH_POLICY_REQUEST_ELEMENT_NAME) + + 3 // >crlf + + 1 // < + + strlen(SERVICE_ELEMENT_NAME) + + 1 // > + + strlen(pServiceName) + + 2 // crlf + + 2 // + + strlen(pHostName) + + 2 // crlf + + 2 // null + + // Allocate the msg buffer + pMsg = (char*) malloc(bufferSize); + if (pMsg) + { + // Now build the message + memset(pMsg, 0, bufferSize); + strcat(pMsg, XML_DECLARATION); + strcat(pMsg, "\r\n"); + strcat(pMsg, "<"); + strcat(pMsg, GET_AUTH_POLICY_REQUEST_ELEMENT_NAME); + strcat(pMsg, ">\r\n"); + strcat(pMsg, "<"); + strcat(pMsg, SERVICE_ELEMENT_NAME); + strcat(pMsg, ">"); + strcat(pMsg, pServiceName); + strcat(pMsg, "\r\n"); + strcat(pMsg, "<"); + strcat(pMsg, HOST_ELEMENT_NAME); + strcat(pMsg, ">"); + strcat(pMsg, pHostName); + strcat(pMsg, "\r\n"); + strcat(pMsg, ""); + } + else + { + DbgTrace(0, "-BuildGetAuthPolicyMsg- Buffer allocation error\n", 0); + } + + DbgTrace(1, "-BuildGetAuthPolicyMsg- End, pMsg = %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: + * + * + * + * ok200 + * authentication policy data + * + * + * When a get authentication policy request fails to be successfully processed, + * the server responds with an error and an error description string. The message + * format of an unsuccessful reply is as follows: + * + * + * + * status descriptionstatus code + * + * + * Plase note that the protocol utilizes the status codes defined + * in the HTTP 1.1 Specification. + * + */ + + // Allocate GetAuthPolicyResp object + pGetAuthPolicyResp = malloc(sizeof(*pGetAuthPolicyResp)); + if (pGetAuthPolicyResp) + { + XML_Parser p; + + // Initialize the GetAuthPolicyResp object and set it in the + // parse oject. + memset(pGetAuthPolicyResp, 0, sizeof(*pGetAuthPolicyResp)); + getAuthPolicyRespParse.pGetAuthPolicyResp = pGetAuthPolicyResp; + + // Create parser + p = XML_ParserCreate(NULL); + if (p) + { + // Keep track of the parser in our parse object + getAuthPolicyRespParse.p = p; + + // Initialize the status within the parse object + getAuthPolicyRespParse.status = CASA_STATUS_SUCCESS; + + // Set the start and end element handlers + XML_SetElementHandler(p, + 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); +} + + +//++======================================================================= +//++======================================================================= +//++======================================================================= + diff --git a/CASA-auth-token/non-java/client/gettokenmsg.c b/CASA-auth-token/non-java/client/gettokenmsg.c new file mode 100644 index 00000000..e25a7218 --- /dev/null +++ b/CASA-auth-token/non-java/client/gettokenmsg.c @@ -0,0 +1,793 @@ +/*********************************************************************** + * + * Copyright (C) 2006 Novell, Inc. All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, Novell, Inc. + * + * To contact Novell about this file by physical or electronic mail, + * you may find current contact information at www.novell.com. + * + * Author: Juan Carlos Luciani + * + ***********************************************************************/ + + +//===[ Include files ]===================================================== + +#include "internal.h" + +//===[ Type definitions ]================================================== + +// +// Parse states +// +#define AWAITING_ROOT_ELEMENT_START 0x0 +#define AWAITING_ROOT_ELEMENT_END 0x1 +#define AWAITING_STATUS_ELEMENT_START 0x2 +#define AWAITING_STATUS_ELEMENT_END 0x3 +#define AWAITING_STATUS_DATA 0x4 +#define AWAITING_DESCRIPTION_ELEMENT_START 0x5 +#define AWAITING_DESCRIPTION_ELEMENT_END 0x6 +#define AWAITING_DESCRIPTION_DATA 0x7 +#define AWAITING_LIFETIME_DATA 0x8 +#define AWAITING_LIFETIME_ELEMENT_START 0x9 +#define AWAITING_LIFETIME_ELEMENT_END 0xA +#define AWAITING_AUTH_TOKEN_ELEMENT_START 0xB +#define AWAITING_AUTH_TOKEN_ELEMENT_END 0xC +#define AWAITING_AUTH_TOKEN_DATA 0xD +#define DONE_PARSING 0xE + +// +// Get Authentication Token Response Parse Structure +// +typedef struct _GetAuthTokenRespParse +{ + XML_Parser p; + int state; + int elementDataProcessed; + GetAuthTokenResp *pGetAuthTokenResp; + CasaStatus status; + +} GetAuthTokenRespParse, *PGetAuthTokenRespParse; + + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + +//++======================================================================= +char* +BuildGetAuthTokenMsg( + IN 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: + * + * + * + * service name + * host name + * session token data + * + * + */ + + // Determine the buffer size necessary to hold the msg + bufferSize = strlen(XML_DECLARATION) + + 2 // crlf + + 1 // < + + strlen(GET_AUTH_TOKEN_REQUEST_ELEMENT_NAME) + + 3 // >crlf + + 1 // < + + strlen(SERVICE_ELEMENT_NAME) + + 1 // > + + strlen(pServiceName) + + 2 // crlf + + 1 // < + + strlen(HOST_ELEMENT_NAME) + + 1 // > + + strlen(pHostName) + + 2 // crlf + + 1 // < + + strlen(SESSION_TOKEN_ELEMENT_NAME) + + 1 // > + + strlen(pSessionToken) + + 2 // crlf + + 2 // null + + // Allocate the msg buffer + pMsg = (char*) malloc(bufferSize); + if (pMsg) + { + // Now build the message + memset(pMsg, 0, bufferSize); + strcat(pMsg, XML_DECLARATION); + strcat(pMsg, "\r\n"); + strcat(pMsg, "<"); + strcat(pMsg, GET_AUTH_TOKEN_REQUEST_ELEMENT_NAME); + strcat(pMsg, ">\r\n"); + strcat(pMsg, "<"); + strcat(pMsg, SERVICE_ELEMENT_NAME); + strcat(pMsg, ">"); + strcat(pMsg, pServiceName); + strcat(pMsg, "\r\n"); + strcat(pMsg, "<"); + strcat(pMsg, HOST_ELEMENT_NAME); + strcat(pMsg, ">"); + strcat(pMsg, pHostName); + strcat(pMsg, "\r\n"); + strcat(pMsg, "<"); + strcat(pMsg, SESSION_TOKEN_ELEMENT_NAME); + strcat(pMsg, ">"); + strcat(pMsg, pSessionToken); + strcat(pMsg, "\r\n"); + strcat(pMsg, ""); + } + else + { + DbgTrace(0, "-BuildGetAuthTokenMsg- Buffer allocation error\n", 0); + } + + DbgTrace(1, "-BuildGetAuthTokenMsg- End, pMsg = %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: + * + * + * + * ok200 + * lifetime valuesession token data + * + * + * When a get authentication token request fails to be successfully processed, + * the server responds with an error and an error description string. The message + * format of an unsuccessful reply is as follows: + * + * + * + * status descriptionstatus code + * + * + * Plase note that the protocol utilizes the status codes defined + * in the HTTP 1.1 Specification. + * + */ + + // Allocate GetAuthTokenResp object + pGetAuthTokenResp = malloc(sizeof(*pGetAuthTokenResp)); + if (pGetAuthTokenResp) + { + XML_Parser p; + + // Initialize the GetAuthTokenResp object and set it in the + // parse oject. + memset(pGetAuthTokenResp, 0, sizeof(*pGetAuthTokenResp)); + getAuthTokenRespParse.pGetAuthTokenResp = pGetAuthTokenResp; + + // Create parser + p = XML_ParserCreate(NULL); + if (p) + { + // Keep track of the parser in our parse object + getAuthTokenRespParse.p = p; + + // Initialize the status within the parse object + getAuthTokenRespParse.status = CASA_STATUS_SUCCESS; + + // Set the start and end element handlers + XML_SetElementHandler(p, + 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); +} + + +//++======================================================================= +//++======================================================================= +//++======================================================================= + diff --git a/CASA-auth-token/non-java/client/internal.h b/CASA-auth-token/non-java/client/internal.h new file mode 100644 index 00000000..c4588c96 --- /dev/null +++ b/CASA-auth-token/non-java/client/internal.h @@ -0,0 +1,395 @@ +/*********************************************************************** + * + * Copyright (C) 2006 Novell, Inc. All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, Novell, Inc. + * + * To contact Novell about this file by physical or electronic mail, + * you may find current contact information at www.novell.com. + * + * Author: Juan Carlos Luciani + * + ***********************************************************************/ + +#ifndef _INTERNAL_H_ +#define _INTERNAL_H_ + +//===[ Include files ]===================================================== + +#include "platform.h" +#include +#include +#include +#include +#include "list_entry.h" +#include "config_if.h" +#include "mech_if.h" +#include "proto.h" + +//===[ Type definitions ]================================================== + +// +// Authentication Context structure +// +typedef struct _AuthContext +{ + LIST_ENTRY listEntry; + char *pContext; + int contextLen; + char *pMechanism; + int mechanismLen; + char *pMechInfo; + int mechInfoLen; + +} AuthContext, *PAuthContext; + +// +// Authentication Policy structure +// +typedef struct _AuthPolicy +{ + LIST_ENTRY authContextListHead; + +} AuthPolicy, *PAuthPolicy; + +// +// Get Authentication Policy Response structure +// +typedef struct _GetAuthPolicyResp +{ + char *pPolicy; + int policyLen; + +} GetAuthPolicyResp, *PGetAuthPolicyResp; + +// +// Get Authentication Token Response structure +// +typedef struct _GetAuthTokenResp +{ + char *pToken; + int tokenLen; + int tokenLifetime; + +} GetAuthTokenResp, *PGetAuthTokenResp; + +// +// Authenticate Response structure +// +typedef struct _AuthenticateResp +{ + char *pToken; + int tokenLen; + int tokenLifetime; + +} AuthenticateResp, *PAuthenticateResp; + + +//===[ 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 +Initialize(void); + +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, + IN CasaStatus status, + IN unsigned char *pToken, + IN int entryLifetime + ); + +extern +AuthCacheEntry* +CreateAuthTokenCacheEntry( + IN const char *pCacheKey, + IN const char *pHostName, + IN CasaStatus status, + IN unsigned char *pToken, + IN int entryLifetime + ); + +extern +void +FreeAuthCacheEntry( + IN AuthCacheEntry *pEntry); + +extern +AuthCacheEntry* +FindSessionTokenEntryInCache( + IN const char *pCacheKey); + +extern +AuthCacheEntry* +FindAuthTokenEntryInCache( + IN const char *pCacheKey, + IN const char *pGroupOrHostName); + +extern +CasaStatus +InitializeAuthCache(void); + +// +// Functions exported by config.c +// + +extern +CasaStatus +GetConfigInterface( + IN const char *pConfigFolder, + IN const char *pConfigName, + INOUT ConfigIf **ppConfigIf); + +// +// Functions exported by platform.c +// + +extern +CasaStatus +CreateUserMutex( + HANDLE *phMutex + ); + +extern +void +AcquireUserMutex( + HANDLE hMutex + ); + +extern +void +ReleaseUserMutex( + HANDLE hMutex + ); + +extern +void +DestroyUserMutex( + HANDLE hMutex + ); + +extern +CasaStatus +CreateInitializationMutex(void); + +extern +void +AcquireInitializationMutex(void); + +extern +void +ReleaseInitializationMutex(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_ + diff --git a/CASA-auth-token/non-java/client/mech_if.h b/CASA-auth-token/non-java/client/mech_if.h new file mode 100644 index 00000000..285d70a8 --- /dev/null +++ b/CASA-auth-token/non-java/client/mech_if.h @@ -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 + * + ***********************************************************************/ + + +#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_ + diff --git a/CASA-auth-token/non-java/client/mechanisms/krb5/Krb5Authenticate.conf b/CASA-auth-token/non-java/client/mechanisms/krb5/Krb5Authenticate.conf new file mode 100644 index 00000000..df843e9f --- /dev/null +++ b/CASA-auth-token/non-java/client/mechanisms/krb5/Krb5Authenticate.conf @@ -0,0 +1,12 @@ +####################################################### +# # +# CASA Authentication Token System configuration file # +# for module: # +# # +# Krb5Authenticate # +# # +####################################################### + +LibraryName \Program Files\novell\casa\lib\krb5mech.dll + + diff --git a/CASA-auth-token/non-java/client/mechanisms/krb5/README b/CASA-auth-token/non-java/client/mechanisms/krb5/README new file mode 100644 index 00000000..6b5f03b1 --- /dev/null +++ b/CASA-auth-token/non-java/client/mechanisms/krb5/README @@ -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. + + + + + + + + + + diff --git a/CASA-auth-token/non-java/client/mechanisms/krb5/TODO b/CASA-auth-token/non-java/client/mechanisms/krb5/TODO new file mode 100644 index 00000000..c7b55ce1 --- /dev/null +++ b/CASA-auth-token/non-java/client/mechanisms/krb5/TODO @@ -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. + diff --git a/CASA-auth-token/non-java/client/mechanisms/krb5/interface.c b/CASA-auth-token/non-java/client/mechanisms/krb5/interface.c new file mode 100644 index 00000000..2fbdf3f4 --- /dev/null +++ b/CASA-auth-token/non-java/client/mechanisms/krb5/interface.c @@ -0,0 +1,207 @@ +/*********************************************************************** + * + * Copyright (C) 2006 Novell, Inc. All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, Novell, Inc. + * + * To contact Novell about this file by physical or electronic mail, + * you may find current contact information at www.novell.com. + * + * Author: Juan Carlos Luciani + * + ***********************************************************************/ + +//===[ Include files ]===================================================== + +#include "internal.h" + +//===[ Type definitions ]================================================== + +// +// Authentication Token Interface instance data +// +typedef struct _AuthTokenIfInstance +{ + int refCount; + AuthTokenIf authTokenIf; + +} AuthTokenIfInstance, *PAuthTokenIfInstance; + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + +// AuthTokenIf variables +static +int g_numAuthTokenIfObjs = 0; + + +//++======================================================================= +static +int SSCS_CALL +AuthTokenIf_AddReference( + IN const void *pIfInstance) +// +// Arguments: +// pIfInstance - +// Pointer to interface object. +// +// Returns: +// Interface reference count. +// +// Description: +// Increases interface reference count. +// +// L2 +//=======================================================================-- +{ + int refCount; + AuthTokenIfInstance *pAuthTokenIfInstance = CONTAINING_RECORD(pIfInstance, AuthTokenIfInstance, authTokenIf); + + DbgTrace(2, "-AuthTokenIf_AddReference- Start\n", 0); + + // Increment the reference count on the object + pAuthTokenIfInstance->refCount ++; + refCount = pAuthTokenIfInstance->refCount; + + DbgTrace(2, "-AuthTokenIf_AddReference- End, refCount = %08X\n", refCount); + + return refCount; +} + + +//++======================================================================= +static +void SSCS_CALL +AuthTokenIf_ReleaseReference( + IN const void *pIfInstance) +// +// Arguments: +// pIfInstance - +// Pointer to interface object. +// +// Returns: +// Nothing. +// +// Description: +// Decreases interface reference count. The interface is deallocated if +// the reference count becomes zero. +// +// L2 +//=======================================================================-- +{ + bool freeObj = false; + AuthTokenIfInstance *pAuthTokenIfInstance = CONTAINING_RECORD(pIfInstance, AuthTokenIfInstance, authTokenIf); + + DbgTrace(2, "-AuthTokenIf_ReleaseReference- Start\n", 0); + + // Decrement the reference count on the object and determine if it needs to + // be released. + pAuthTokenIfInstance->refCount --; + if (pAuthTokenIfInstance->refCount == 0) + { + // The object needs to be released, forget about it. + freeObj = true; + g_numAuthTokenIfObjs --; + } + + // Free object if necessary + if (freeObj) + free(pAuthTokenIfInstance); + + DbgTrace(2, "-AuthTokenIf_ReleaseReference- End\n", 0); +} + + +//++======================================================================= +CasaStatus SSCS_CALL +GET_AUTH_TOKEN_INTERFACE_RTN( + IN const ConfigIf *pModuleConfigIf, + INOUT AuthTokenIf **ppAuthTokenIf) +// +// Arguments: +// pModuleConfigIf - +// Pointer to configuration interface instance for the module. +// +// ppAuthTokenIf - +// Pointer to variable that will receive pointer to AuthTokenIf +// instance. +// +// Returns: +// Casa Status +// +// Description: +// Gets authentication token interface instance. +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus; + AuthTokenIfInstance *pAuthTokenIfInstance; + + + DbgTrace(1, "-GetAuthTokenInterface- Start\n", 0); + + // Validate input parameters + if (pModuleConfigIf == NULL + || ppAuthTokenIf == NULL) + { + DbgTrace(0, "-GetAuthTokenInterface- Invalid input parameter\n", 0); + + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_PWTOKEN, + CASA_STATUS_INVALID_PARAMETER); + goto exit; + } + + // Allocate space for the interface instance + pAuthTokenIfInstance = malloc(sizeof(*pAuthTokenIfInstance)); + if (pAuthTokenIfInstance) + { + // Initialize the interface instance data + pAuthTokenIfInstance->refCount = 1; + pAuthTokenIfInstance->authTokenIf.addReference = AuthTokenIf_AddReference; + pAuthTokenIfInstance->authTokenIf.releaseReference = AuthTokenIf_ReleaseReference; + pAuthTokenIfInstance->authTokenIf.getAuthToken = AuthTokenIf_GetAuthToken; + + // Keep track of this object + g_numAuthTokenIfObjs ++; + + // Return the interface to the caller + *ppAuthTokenIf = &pAuthTokenIfInstance->authTokenIf; + + // Success + retStatus = CASA_STATUS_SUCCESS; + } + else + { + DbgTrace(0, "-GetAuthTokenInterface- Buffer allocation failure\n", 0); + + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_PWTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + +exit: + + DbgTrace(1, "-GetAuthTokenInterface- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +//++======================================================================= +//++======================================================================= + diff --git a/CASA-auth-token/non-java/client/mechanisms/krb5/internal.h b/CASA-auth-token/non-java/client/mechanisms/krb5/internal.h new file mode 100644 index 00000000..dad21ef1 --- /dev/null +++ b/CASA-auth-token/non-java/client/mechanisms/krb5/internal.h @@ -0,0 +1,90 @@ +/*********************************************************************** + * + * Copyright (C) 2006 Novell, Inc. All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, Novell, Inc. + * + * To contact Novell about this file by physical or electronic mail, + * you may find current contact information at www.novell.com. + * + * Author: Juan Carlos Luciani + * + ***********************************************************************/ + +#ifndef _INTERNAL_H_ +#define _INTERNAL_H_ + +//===[ Include files ]===================================================== + +#include "platform.h" +#include +#include +#include "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_ diff --git a/CASA-auth-token/non-java/client/mechanisms/krb5/krb5.vcproj b/CASA-auth-token/non-java/client/mechanisms/krb5/krb5.vcproj new file mode 100644 index 00000000..082bf892 --- /dev/null +++ b/CASA-auth-token/non-java/client/mechanisms/krb5/krb5.vcproj @@ -0,0 +1,182 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CASA-auth-token/non-java/client/mechanisms/krb5/util.c b/CASA-auth-token/non-java/client/mechanisms/krb5/util.c new file mode 100644 index 00000000..90454c7a --- /dev/null +++ b/CASA-auth-token/non-java/client/mechanisms/krb5/util.c @@ -0,0 +1,282 @@ +/*********************************************************************** + * + * Copyright (C) 2006 Novell, Inc. All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, Novell, Inc. + * + * To contact Novell about this file by physical or electronic mail, + * you may find current contact information at www.novell.com. + * + * Author: Juan Carlos Luciani + * + ***********************************************************************/ + +//===[ Include files ]===================================================== + +#include "internal.h" + +//===[ Type definitions ]================================================== + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + +// Debug Level +int DebugLevel = 0; + +// Tables for Base64 encoding and decoding +static const int8_t g_Base64[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +static const uint8_t g_Expand64[256] = +{ + /* ASCII table */ + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64, + 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64, + 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 +}; + + +//++======================================================================= +CasaStatus +EncodeData( + IN const void *pData, + IN const int32_t dataLen, + INOUT char **ppEncodedData, + INOUT int32_t *pEncodedDataLen) +// +// Arguments: +// +// Returns: +// +// Description: +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus; + int encodedSize; + + char *pTmp; + + DbgTrace(3, "-EncodeData- Start\n", 0); + + // Determine the encoded size and allocate a buffer to hold the encoded data + encodedSize = ((dataLen * 4 + 2) / 3) - (dataLen % 3 ) + 4; + pTmp = (char*) malloc(encodedSize); + *ppEncodedData = pTmp; + if (*ppEncodedData) + { + uint8_t *pOut, *pIn; + int i; + + // Setup pointers to move through the buffers + pIn = (uint8_t*) pData; + pOut = (uint8_t*) *ppEncodedData; + + // Perform the encoding + for (i = 0; i < dataLen - 2; i += 3) + { + *pOut++ = g_Base64[(pIn[i] >> 2) & 0x3F]; + *pOut++ = g_Base64[((pIn[i] & 0x3) << 4) | + ((int32_t)(pIn[i + 1] & 0xF0) >> 4)]; + *pOut++ = g_Base64[((pIn[i + 1] & 0xF) << 2) | + ((int32_t)(pIn[i + 2] & 0xC0) >> 6)]; + *pOut++ = g_Base64[pIn[i + 2] & 0x3F]; + } + if (i < dataLen) + { + *pOut++ = g_Base64[(pIn[i] >> 2) & 0x3F]; + if (i == (dataLen - 1)) + { + *pOut++ = g_Base64[((pIn[i] & 0x3) << 4)]; + *pOut++ = '='; + } + else + { + *pOut++ = g_Base64[((pIn[i] & 0x3) << 4) | + ((int32_t)(pIn[i + 1] & 0xF0) >> 4)]; + *pOut++ = g_Base64[((pIn[i + 1] & 0xF) << 2)]; + } + *pOut++ = '='; + } + *pOut++ = '\0'; + + // Return the encoded data length + *pEncodedDataLen = (int32_t)(pOut - (uint8_t*)*ppEncodedData); + + // Success + retStatus = CASA_STATUS_SUCCESS; + } + else + { + DbgTrace(0, "-EncodeData- Buffer allocation failure\n", 0); + + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_PWTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + + DbgTrace(3, "-EncodeData- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +CasaStatus +DecodeData( + IN const char *pEncodedData, + IN const int32_t encodedDataLen, // Does not include NULL terminator + INOUT void **ppData, + INOUT int32_t *pDataLen) +// +// Arguments: +// +// Returns: +// +// Description: +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus; + int i, j; + int decodedSize; + + DbgTrace(3, "-DecodeData- Start\n", 0); + + // Determine the decoded size + for (i = 0, j = 0; i < encodedDataLen; i++) + if (g_Expand64[((uint8_t*) pEncodedData)[i]] < 64) + j++; + decodedSize = (j * 3 + 3) / 4; + + // Allocate buffer to hold the decoded data + *ppData = malloc(decodedSize); + if (*ppData) + { + bool endReached = false; + uint8_t c0, c1, c2, c3; + uint8_t *p, *q; + + // Initialize parameters that will be used during the decode operation + c0 = c1 = c2 = c3 = 0; + p = (uint8_t*) pEncodedData; + q = (uint8_t*) *ppData; + + // Decode the data + // + // Loop through the data, piecing back information. Any newlines, and/or + // carriage returns need to be skipped. + while (j > 4) + { + while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p))) + p++; + if (64 == g_Expand64[*p]) + { + endReached = true; + break; + } + c0 = *(p++); + + while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p))) + p++; + if (64 == g_Expand64[*p]) + { + *(q++) = (uint8_t)(g_Expand64[c0] << 2); + j--; + endReached = true; + break; + } + c1 = *(p++); + + while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p))) + p++; + if (64 == g_Expand64[*p]) + { + *(q++) = (uint8_t)(g_Expand64[c0] << 2 | g_Expand64[c1] >> 4); + *(q++) = (uint8_t)(g_Expand64[c1] << 4); + j -= 2; + endReached = true; + break; + } + c2 = *(p++); + + while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p))) + p++; + if (64 == g_Expand64[*p]) + { + *(q++) = (uint8_t)(g_Expand64[c0] << 2 | g_Expand64[c1] >> 4); + *(q++) = (uint8_t)(g_Expand64[c1] << 4 | g_Expand64[c2] >> 2); + *(q++) = (uint8_t)(g_Expand64[c2] << 6); + j -= 3; + endReached = true; + break; + } + c3 = *(p++); + + *(q++) = (uint8_t)(g_Expand64[c0] << 2 | g_Expand64[c1] >> 4); + *(q++) = (uint8_t)(g_Expand64[c1] << 4 | g_Expand64[c2] >> 2); + *(q++) = (uint8_t)(g_Expand64[c2] << 6 | g_Expand64[c3]); + j -= 4; + } + if (!endReached) + { + if (j > 1) + *(q++) = (uint8_t)(g_Expand64[*p] << 2 | g_Expand64[p[1]] >> 4); + if (j > 2) + *(q++) = (uint8_t)(g_Expand64[p[1]] << 4 | g_Expand64[p[2]] >> 2); + if (j > 3) + *(q++) = (uint8_t)(g_Expand64[p[2]] << 6 | g_Expand64[p[3]]); + } + + // Return the length of the decoded data + *pDataLen = (int32_t)(q - (uint8_t*)*ppData); + + // Success + retStatus = CASA_STATUS_SUCCESS; + } + else + { + DbgTrace(0, "-DecodeData- Buffer allocation failure\n", 0); + + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_PWTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + + DbgTrace(3, "-DecodeData- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +//++======================================================================= +//++======================================================================= + diff --git a/CASA-auth-token/non-java/client/mechanisms/krb5/windows/dllsup.c b/CASA-auth-token/non-java/client/mechanisms/krb5/windows/dllsup.c new file mode 100644 index 00000000..1fbf8cc8 --- /dev/null +++ b/CASA-auth-token/non-java/client/mechanisms/krb5/windows/dllsup.c @@ -0,0 +1,132 @@ +/*********************************************************************** + * + * Copyright (C) 2006 Novell, Inc. All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, Novell, Inc. + * + * To contact Novell about this file by physical or electronic mail, + * you may find current contact information at www.novell.com. + * + * Author: Juan Carlos Luciani + * + ***********************************************************************/ + +//===[ Include files ]===================================================== + +#include "internal.h" + +//===[ External data ]===================================================== + +//===[ Manifest constants ]================================================ + +//===[ Type definitions ]================================================== + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + +UINT32 g_ulCount = 0; +UINT32 g_ulLock = 0; +HANDLE g_hModule; + + +//++======================================================================= +BOOL APIENTRY DllMain( + HANDLE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +//=======================================================================-- +{ + BOOL retStatus = TRUE; + + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + { + g_hModule = hModule; + + // Initialize the library + if (InitializeLibrary() != 0) + { + // Failed to initialize the library + OutputDebugString("CASA_KRB5_MECH -DllMain- Library initialization failed\n"); + retStatus = FALSE; + } + break; + } + + case DLL_THREAD_ATTACH: + { + g_hModule = hModule; + break; + } + + case DLL_THREAD_DETACH: + break; + + case DLL_PROCESS_DETACH: + { + /* Don't uninitialize on windows + tbd + */ + break; + } + } + + return retStatus; +} + +//++======================================================================= +// +// DllCanUnloadNow +// +// Synopsis +// +// +STDAPI +DllCanUnloadNow() +// +// Input Arguments +// +// Ouput Arguments +// +// Return Value +// S_OK The DLL can be unloaded. +// S_FALSE The DLL cannot be unloaded now. +// +// Description +// An Exported Function. +// DLLs that support the OLE Component Object Model (COM) should implement +// and export DllCanUnloadNow. +// A call to DllCanUnloadNow determines whether the DLL from which it is +// exported is still in use. A DLL is no longer in use when it is not +// managing any existing objects (the reference count on all of its objects +// is 0). +// DllCanUnloadNow returns S_FALSE if there are any existing references to +// objects that the DLL manages. +// +// Environment +// +// See Also +// +//=======================================================================-- +{ + // tbd + return ((g_ulCount == 0 && g_ulLock == 0) ? S_OK : S_FALSE); +} + +//========================================================================= +//========================================================================= + diff --git a/CASA-auth-token/non-java/client/mechanisms/krb5/windows/get.c b/CASA-auth-token/non-java/client/mechanisms/krb5/windows/get.c new file mode 100644 index 00000000..a3ac6000 --- /dev/null +++ b/CASA-auth-token/non-java/client/mechanisms/krb5/windows/get.c @@ -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 + * + ***********************************************************************/ + + +//===[ 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; +} + + +//++======================================================================= +//++======================================================================= +//++======================================================================= + diff --git a/CASA-auth-token/non-java/client/mechanisms/krb5/windows/krb5mech.def b/CASA-auth-token/non-java/client/mechanisms/krb5/windows/krb5mech.def new file mode 100644 index 00000000..1605afcf --- /dev/null +++ b/CASA-auth-token/non-java/client/mechanisms/krb5/windows/krb5mech.def @@ -0,0 +1,10 @@ +LIBRARY KRB5MECH +DESCRIPTION 'CASA Kerberos V Authentication Mechanism Library.' + + +EXPORTS +; DllRegisterServer PRIVATE +; DllUnregisterServer PRIVATE +; DllGetClassObject PRIVATE + GetAuthTokenInterface PRIVATE +; DllCanUnloadNow PRIVATE \ No newline at end of file diff --git a/CASA-auth-token/non-java/client/mechanisms/krb5/windows/platform.c b/CASA-auth-token/non-java/client/mechanisms/krb5/windows/platform.c new file mode 100644 index 00000000..869b581c --- /dev/null +++ b/CASA-auth-token/non-java/client/mechanisms/krb5/windows/platform.c @@ -0,0 +1,35 @@ +/*********************************************************************** + * + * Copyright (C) 2006 Novell, Inc. All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, Novell, Inc. + * + * To contact Novell about this file by physical or electronic mail, + * you may find current contact information at www.novell.com. + * + * Author: Juan Carlos Luciani + * + ***********************************************************************/ + +//===[ Include files ]===================================================== + +#include "internal.h" + +//===[ Type definitions ]================================================== + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + + diff --git a/CASA-auth-token/non-java/client/mechanisms/krb5/windows/platform.h b/CASA-auth-token/non-java/client/mechanisms/krb5/windows/platform.h new file mode 100644 index 00000000..1b3f0f7f --- /dev/null +++ b/CASA-auth-token/non-java/client/mechanisms/krb5/windows/platform.h @@ -0,0 +1,83 @@ +/*********************************************************************** + * + * Copyright (C) 2006 Novell, Inc. All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, Novell, Inc. + * + * To contact Novell about this file by physical or electronic mail, + * you may find current contact information at www.novell.com. + * + * Author: Juan Carlos Luciani + * + ***********************************************************************/ + +#ifndef _PLATFORM_H_ +#define _PLATFORM_H_ + +//===[ Include files ]===================================================== + +#include +#include +#include +#include +#include + +//===[ Type definitions ]================================================== + +#ifndef CONTAINING_RECORD +#define CONTAINING_RECORD(address, type, field) ((type *)( \ + (char*)(address) - \ + (char*)(&((type *)0)->field))) +#endif + +// +// DbgTrace macro define +// +//#define DbgTrace(LEVEL, X, Y) { \ +//char printBuff[256]; \ +// if (LEVEL == 0 || DebugLevel >= LEVEL) \ +// { \ +// _snprintf(printBuff, sizeof(printBuff), X, Y); \ +// printf("Krb5Mech %s", printBuff); \ +// } \ +//} +#define DbgTrace(LEVEL, X, Y) { \ +char formatBuff[128]; \ +char printBuff[256]; \ + if (LEVEL == 0 || DebugLevel >= LEVEL) \ + { \ + strcpy(formatBuff, "Krb5Mech "); \ + strncat(formatBuff, X, sizeof(formatBuff) - 9); \ + _snprintf(printBuff, sizeof(printBuff), formatBuff, Y); \ + OutputDebugString(printBuff); \ + } \ +} + +#define bool BOOLEAN +#define true TRUE +#define false FALSE + +//===[ Inlines functions ]=============================================== + +//===[ Function prototypes ]=============================================== + +//===[ Global externals ]================================================== + +//===[ External prototypes ]=============================================== + + +//========================================================================= + +#endif // _PLATFORM_H_ + diff --git a/CASA-auth-token/non-java/client/mechanisms/pwd/PwdAuthenticate.conf b/CASA-auth-token/non-java/client/mechanisms/pwd/PwdAuthenticate.conf new file mode 100644 index 00000000..171f06e0 --- /dev/null +++ b/CASA-auth-token/non-java/client/mechanisms/pwd/PwdAuthenticate.conf @@ -0,0 +1,12 @@ +####################################################### +# # +# CASA Authentication Token System configuration file # +# for module: # +# # +# PwdAuthenticate # +# # +####################################################### + +LibraryName \Program Files\novell\casa\lib\pwmech.dll + + diff --git a/CASA-auth-token/non-java/client/mechanisms/pwd/README b/CASA-auth-token/non-java/client/mechanisms/pwd/README new file mode 100644 index 00000000..12f170d6 --- /dev/null +++ b/CASA-auth-token/non-java/client/mechanisms/pwd/README @@ -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. + + + + + + + + + + diff --git a/CASA-auth-token/non-java/client/mechanisms/pwd/TODO b/CASA-auth-token/non-java/client/mechanisms/pwd/TODO new file mode 100644 index 00000000..cf307b20 --- /dev/null +++ b/CASA-auth-token/non-java/client/mechanisms/pwd/TODO @@ -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. + diff --git a/CASA-auth-token/non-java/client/mechanisms/pwd/get.c b/CASA-auth-token/non-java/client/mechanisms/pwd/get.c new file mode 100644 index 00000000..f2b88546 --- /dev/null +++ b/CASA-auth-token/non-java/client/mechanisms/pwd/get.c @@ -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 + * + ***********************************************************************/ + + +//===[ 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; +} + + +//++======================================================================= +//++======================================================================= +//++======================================================================= + diff --git a/CASA-auth-token/non-java/client/mechanisms/pwd/interface.c b/CASA-auth-token/non-java/client/mechanisms/pwd/interface.c new file mode 100644 index 00000000..2fbdf3f4 --- /dev/null +++ b/CASA-auth-token/non-java/client/mechanisms/pwd/interface.c @@ -0,0 +1,207 @@ +/*********************************************************************** + * + * Copyright (C) 2006 Novell, Inc. All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, Novell, Inc. + * + * To contact Novell about this file by physical or electronic mail, + * you may find current contact information at www.novell.com. + * + * Author: Juan Carlos Luciani + * + ***********************************************************************/ + +//===[ Include files ]===================================================== + +#include "internal.h" + +//===[ Type definitions ]================================================== + +// +// Authentication Token Interface instance data +// +typedef struct _AuthTokenIfInstance +{ + int refCount; + AuthTokenIf authTokenIf; + +} AuthTokenIfInstance, *PAuthTokenIfInstance; + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + +// AuthTokenIf variables +static +int g_numAuthTokenIfObjs = 0; + + +//++======================================================================= +static +int SSCS_CALL +AuthTokenIf_AddReference( + IN const void *pIfInstance) +// +// Arguments: +// pIfInstance - +// Pointer to interface object. +// +// Returns: +// Interface reference count. +// +// Description: +// Increases interface reference count. +// +// L2 +//=======================================================================-- +{ + int refCount; + AuthTokenIfInstance *pAuthTokenIfInstance = CONTAINING_RECORD(pIfInstance, AuthTokenIfInstance, authTokenIf); + + DbgTrace(2, "-AuthTokenIf_AddReference- Start\n", 0); + + // Increment the reference count on the object + pAuthTokenIfInstance->refCount ++; + refCount = pAuthTokenIfInstance->refCount; + + DbgTrace(2, "-AuthTokenIf_AddReference- End, refCount = %08X\n", refCount); + + return refCount; +} + + +//++======================================================================= +static +void SSCS_CALL +AuthTokenIf_ReleaseReference( + IN const void *pIfInstance) +// +// Arguments: +// pIfInstance - +// Pointer to interface object. +// +// Returns: +// Nothing. +// +// Description: +// Decreases interface reference count. The interface is deallocated if +// the reference count becomes zero. +// +// L2 +//=======================================================================-- +{ + bool freeObj = false; + AuthTokenIfInstance *pAuthTokenIfInstance = CONTAINING_RECORD(pIfInstance, AuthTokenIfInstance, authTokenIf); + + DbgTrace(2, "-AuthTokenIf_ReleaseReference- Start\n", 0); + + // Decrement the reference count on the object and determine if it needs to + // be released. + pAuthTokenIfInstance->refCount --; + if (pAuthTokenIfInstance->refCount == 0) + { + // The object needs to be released, forget about it. + freeObj = true; + g_numAuthTokenIfObjs --; + } + + // Free object if necessary + if (freeObj) + free(pAuthTokenIfInstance); + + DbgTrace(2, "-AuthTokenIf_ReleaseReference- End\n", 0); +} + + +//++======================================================================= +CasaStatus SSCS_CALL +GET_AUTH_TOKEN_INTERFACE_RTN( + IN const ConfigIf *pModuleConfigIf, + INOUT AuthTokenIf **ppAuthTokenIf) +// +// Arguments: +// pModuleConfigIf - +// Pointer to configuration interface instance for the module. +// +// ppAuthTokenIf - +// Pointer to variable that will receive pointer to AuthTokenIf +// instance. +// +// Returns: +// Casa Status +// +// Description: +// Gets authentication token interface instance. +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus; + AuthTokenIfInstance *pAuthTokenIfInstance; + + + DbgTrace(1, "-GetAuthTokenInterface- Start\n", 0); + + // Validate input parameters + if (pModuleConfigIf == NULL + || ppAuthTokenIf == NULL) + { + DbgTrace(0, "-GetAuthTokenInterface- Invalid input parameter\n", 0); + + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_PWTOKEN, + CASA_STATUS_INVALID_PARAMETER); + goto exit; + } + + // Allocate space for the interface instance + pAuthTokenIfInstance = malloc(sizeof(*pAuthTokenIfInstance)); + if (pAuthTokenIfInstance) + { + // Initialize the interface instance data + pAuthTokenIfInstance->refCount = 1; + pAuthTokenIfInstance->authTokenIf.addReference = AuthTokenIf_AddReference; + pAuthTokenIfInstance->authTokenIf.releaseReference = AuthTokenIf_ReleaseReference; + pAuthTokenIfInstance->authTokenIf.getAuthToken = AuthTokenIf_GetAuthToken; + + // Keep track of this object + g_numAuthTokenIfObjs ++; + + // Return the interface to the caller + *ppAuthTokenIf = &pAuthTokenIfInstance->authTokenIf; + + // Success + retStatus = CASA_STATUS_SUCCESS; + } + else + { + DbgTrace(0, "-GetAuthTokenInterface- Buffer allocation failure\n", 0); + + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_PWTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + +exit: + + DbgTrace(1, "-GetAuthTokenInterface- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +//++======================================================================= +//++======================================================================= + diff --git a/CASA-auth-token/non-java/client/mechanisms/pwd/internal.h b/CASA-auth-token/non-java/client/mechanisms/pwd/internal.h new file mode 100644 index 00000000..3ac0c0cd --- /dev/null +++ b/CASA-auth-token/non-java/client/mechanisms/pwd/internal.h @@ -0,0 +1,92 @@ +/*********************************************************************** + * + * Copyright (C) 2006 Novell, Inc. All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, Novell, Inc. + * + * To contact Novell about this file by physical or electronic mail, + * you may find current contact information at www.novell.com. + * + * Author: Juan Carlos Luciani + * + ***********************************************************************/ + +#ifndef _INTERNAL_H_ +#define _INTERNAL_H_ + +//===[ Include files ]===================================================== + +#include "platform.h" +#include +#include +#include +#include +#include "config_if.h" +#include "mech_if.h" + +//===[ Type definitions ]================================================== + +//===[ Inlines functions ]=============================================== + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + +//===[ Global externals ]================================================== + +extern int DebugLevel; + +//===[ External prototypes ]=============================================== + +// +// Defined in get.c +// + +extern +CasaStatus SSCS_CALL +AuthTokenIf_GetAuthToken( + IN const void *pIfInstance, + IN const char *pContext, + IN const char *pMechInfo, + INOUT char *pTokenBuf, + INOUT int *pTokenBufLen); + +extern +int +InitializeLibrary(void); + +// +// Defined in utils.c +// + +extern +CasaStatus +EncodeData( + IN const void *pData, + IN const int32_t dataLen, + INOUT char **ppEncodedData, + INOUT int32_t *pEncodedDataLen); + +extern +CasaStatus +DecodeData( + IN const char *pEncodedData, + IN const int32_t encodedDataLen, // Does not include NULL terminator + INOUT void **ppData, + INOUT int32_t *pDataLen); + +//========================================================================= + +#endif // _INTERNAL_H_ + diff --git a/CASA-auth-token/non-java/client/mechanisms/pwd/pwd.vcproj b/CASA-auth-token/non-java/client/mechanisms/pwd/pwd.vcproj new file mode 100644 index 00000000..40ee722e --- /dev/null +++ b/CASA-auth-token/non-java/client/mechanisms/pwd/pwd.vcproj @@ -0,0 +1,183 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CASA-auth-token/non-java/client/mechanisms/pwd/util.c b/CASA-auth-token/non-java/client/mechanisms/pwd/util.c new file mode 100644 index 00000000..90454c7a --- /dev/null +++ b/CASA-auth-token/non-java/client/mechanisms/pwd/util.c @@ -0,0 +1,282 @@ +/*********************************************************************** + * + * Copyright (C) 2006 Novell, Inc. All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, Novell, Inc. + * + * To contact Novell about this file by physical or electronic mail, + * you may find current contact information at www.novell.com. + * + * Author: Juan Carlos Luciani + * + ***********************************************************************/ + +//===[ Include files ]===================================================== + +#include "internal.h" + +//===[ Type definitions ]================================================== + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + +// Debug Level +int DebugLevel = 0; + +// Tables for Base64 encoding and decoding +static const int8_t g_Base64[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +static const uint8_t g_Expand64[256] = +{ + /* ASCII table */ + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64, + 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64, + 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 +}; + + +//++======================================================================= +CasaStatus +EncodeData( + IN const void *pData, + IN const int32_t dataLen, + INOUT char **ppEncodedData, + INOUT int32_t *pEncodedDataLen) +// +// Arguments: +// +// Returns: +// +// Description: +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus; + int encodedSize; + + char *pTmp; + + DbgTrace(3, "-EncodeData- Start\n", 0); + + // Determine the encoded size and allocate a buffer to hold the encoded data + encodedSize = ((dataLen * 4 + 2) / 3) - (dataLen % 3 ) + 4; + pTmp = (char*) malloc(encodedSize); + *ppEncodedData = pTmp; + if (*ppEncodedData) + { + uint8_t *pOut, *pIn; + int i; + + // Setup pointers to move through the buffers + pIn = (uint8_t*) pData; + pOut = (uint8_t*) *ppEncodedData; + + // Perform the encoding + for (i = 0; i < dataLen - 2; i += 3) + { + *pOut++ = g_Base64[(pIn[i] >> 2) & 0x3F]; + *pOut++ = g_Base64[((pIn[i] & 0x3) << 4) | + ((int32_t)(pIn[i + 1] & 0xF0) >> 4)]; + *pOut++ = g_Base64[((pIn[i + 1] & 0xF) << 2) | + ((int32_t)(pIn[i + 2] & 0xC0) >> 6)]; + *pOut++ = g_Base64[pIn[i + 2] & 0x3F]; + } + if (i < dataLen) + { + *pOut++ = g_Base64[(pIn[i] >> 2) & 0x3F]; + if (i == (dataLen - 1)) + { + *pOut++ = g_Base64[((pIn[i] & 0x3) << 4)]; + *pOut++ = '='; + } + else + { + *pOut++ = g_Base64[((pIn[i] & 0x3) << 4) | + ((int32_t)(pIn[i + 1] & 0xF0) >> 4)]; + *pOut++ = g_Base64[((pIn[i + 1] & 0xF) << 2)]; + } + *pOut++ = '='; + } + *pOut++ = '\0'; + + // Return the encoded data length + *pEncodedDataLen = (int32_t)(pOut - (uint8_t*)*ppEncodedData); + + // Success + retStatus = CASA_STATUS_SUCCESS; + } + else + { + DbgTrace(0, "-EncodeData- Buffer allocation failure\n", 0); + + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_PWTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + + DbgTrace(3, "-EncodeData- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +CasaStatus +DecodeData( + IN const char *pEncodedData, + IN const int32_t encodedDataLen, // Does not include NULL terminator + INOUT void **ppData, + INOUT int32_t *pDataLen) +// +// Arguments: +// +// Returns: +// +// Description: +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus; + int i, j; + int decodedSize; + + DbgTrace(3, "-DecodeData- Start\n", 0); + + // Determine the decoded size + for (i = 0, j = 0; i < encodedDataLen; i++) + if (g_Expand64[((uint8_t*) pEncodedData)[i]] < 64) + j++; + decodedSize = (j * 3 + 3) / 4; + + // Allocate buffer to hold the decoded data + *ppData = malloc(decodedSize); + if (*ppData) + { + bool endReached = false; + uint8_t c0, c1, c2, c3; + uint8_t *p, *q; + + // Initialize parameters that will be used during the decode operation + c0 = c1 = c2 = c3 = 0; + p = (uint8_t*) pEncodedData; + q = (uint8_t*) *ppData; + + // Decode the data + // + // Loop through the data, piecing back information. Any newlines, and/or + // carriage returns need to be skipped. + while (j > 4) + { + while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p))) + p++; + if (64 == g_Expand64[*p]) + { + endReached = true; + break; + } + c0 = *(p++); + + while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p))) + p++; + if (64 == g_Expand64[*p]) + { + *(q++) = (uint8_t)(g_Expand64[c0] << 2); + j--; + endReached = true; + break; + } + c1 = *(p++); + + while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p))) + p++; + if (64 == g_Expand64[*p]) + { + *(q++) = (uint8_t)(g_Expand64[c0] << 2 | g_Expand64[c1] >> 4); + *(q++) = (uint8_t)(g_Expand64[c1] << 4); + j -= 2; + endReached = true; + break; + } + c2 = *(p++); + + while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p))) + p++; + if (64 == g_Expand64[*p]) + { + *(q++) = (uint8_t)(g_Expand64[c0] << 2 | g_Expand64[c1] >> 4); + *(q++) = (uint8_t)(g_Expand64[c1] << 4 | g_Expand64[c2] >> 2); + *(q++) = (uint8_t)(g_Expand64[c2] << 6); + j -= 3; + endReached = true; + break; + } + c3 = *(p++); + + *(q++) = (uint8_t)(g_Expand64[c0] << 2 | g_Expand64[c1] >> 4); + *(q++) = (uint8_t)(g_Expand64[c1] << 4 | g_Expand64[c2] >> 2); + *(q++) = (uint8_t)(g_Expand64[c2] << 6 | g_Expand64[c3]); + j -= 4; + } + if (!endReached) + { + if (j > 1) + *(q++) = (uint8_t)(g_Expand64[*p] << 2 | g_Expand64[p[1]] >> 4); + if (j > 2) + *(q++) = (uint8_t)(g_Expand64[p[1]] << 4 | g_Expand64[p[2]] >> 2); + if (j > 3) + *(q++) = (uint8_t)(g_Expand64[p[2]] << 6 | g_Expand64[p[3]]); + } + + // Return the length of the decoded data + *pDataLen = (int32_t)(q - (uint8_t*)*ppData); + + // Success + retStatus = CASA_STATUS_SUCCESS; + } + else + { + DbgTrace(0, "-DecodeData- Buffer allocation failure\n", 0); + + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_PWTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + + DbgTrace(3, "-DecodeData- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +//++======================================================================= +//++======================================================================= + diff --git a/CASA-auth-token/non-java/client/mechanisms/pwd/windows/dllsup.c b/CASA-auth-token/non-java/client/mechanisms/pwd/windows/dllsup.c new file mode 100644 index 00000000..8eecacef --- /dev/null +++ b/CASA-auth-token/non-java/client/mechanisms/pwd/windows/dllsup.c @@ -0,0 +1,132 @@ +/*********************************************************************** + * + * Copyright (C) 2006 Novell, Inc. All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, Novell, Inc. + * + * To contact Novell about this file by physical or electronic mail, + * you may find current contact information at www.novell.com. + * + * Author: Juan Carlos Luciani + * + ***********************************************************************/ + +//===[ Include files ]===================================================== + +#include "internal.h" + +//===[ External data ]===================================================== + +//===[ Manifest constants ]================================================ + +//===[ Type definitions ]================================================== + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + +UINT32 g_ulCount = 0; +UINT32 g_ulLock = 0; +HANDLE g_hModule; + + +//++======================================================================= +BOOL APIENTRY DllMain( + HANDLE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +//=======================================================================-- +{ + BOOL retStatus = TRUE; + + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + { + g_hModule = hModule; + + // Initialize the library + if (InitializeLibrary() != 0) + { + // Failed to initialize the library + OutputDebugString("CASA_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); +} + +//========================================================================= +//========================================================================= + diff --git a/CASA-auth-token/non-java/client/mechanisms/pwd/windows/platform.c b/CASA-auth-token/non-java/client/mechanisms/pwd/windows/platform.c new file mode 100644 index 00000000..869b581c --- /dev/null +++ b/CASA-auth-token/non-java/client/mechanisms/pwd/windows/platform.c @@ -0,0 +1,35 @@ +/*********************************************************************** + * + * Copyright (C) 2006 Novell, Inc. All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, Novell, Inc. + * + * To contact Novell about this file by physical or electronic mail, + * you may find current contact information at www.novell.com. + * + * Author: Juan Carlos Luciani + * + ***********************************************************************/ + +//===[ Include files ]===================================================== + +#include "internal.h" + +//===[ Type definitions ]================================================== + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + + diff --git a/CASA-auth-token/non-java/client/mechanisms/pwd/windows/platform.h b/CASA-auth-token/non-java/client/mechanisms/pwd/windows/platform.h new file mode 100644 index 00000000..ece8baa3 --- /dev/null +++ b/CASA-auth-token/non-java/client/mechanisms/pwd/windows/platform.h @@ -0,0 +1,81 @@ +/*********************************************************************** + * + * Copyright (C) 2006 Novell, Inc. All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, Novell, Inc. + * + * To contact Novell about this file by physical or electronic mail, + * you may find current contact information at www.novell.com. + * + * Author: Juan Carlos Luciani + * + ***********************************************************************/ + +#ifndef _PLATFORM_H_ +#define _PLATFORM_H_ + +//===[ Include files ]===================================================== + +#include +#include +#include + +//===[ Type definitions ]================================================== + +#ifndef CONTAINING_RECORD +#define CONTAINING_RECORD(address, type, field) ((type *)( \ + (char*)(address) - \ + (char*)(&((type *)0)->field))) +#endif + +// +// DbgTrace macro define +// +//#define DbgTrace(LEVEL, X, Y) { \ +//char printBuff[256]; \ +// if (LEVEL == 0 || DebugLevel >= LEVEL) \ +// { \ +// _snprintf(printBuff, sizeof(printBuff), X, Y); \ +// printf("PwdMech %s", printBuff); \ +// } \ +//} +#define DbgTrace(LEVEL, X, Y) { \ +char formatBuff[128]; \ +char printBuff[256]; \ + if (LEVEL == 0 || DebugLevel >= LEVEL) \ + { \ + strcpy(formatBuff, "PwdMech "); \ + strncat(formatBuff, X, sizeof(formatBuff) - 8); \ + _snprintf(printBuff, sizeof(printBuff), formatBuff, Y); \ + OutputDebugString(printBuff); \ + } \ +} + +#define bool BOOLEAN +#define true TRUE +#define false FALSE + +//===[ Inlines functions ]=============================================== + +//===[ Function prototypes ]=============================================== + +//===[ Global externals ]================================================== + +//===[ External prototypes ]=============================================== + + +//========================================================================= + +#endif // _PLATFORM_H_ + diff --git a/CASA-auth-token/non-java/client/mechanisms/pwd/windows/pwmech.def b/CASA-auth-token/non-java/client/mechanisms/pwd/windows/pwmech.def new file mode 100644 index 00000000..0557e401 --- /dev/null +++ b/CASA-auth-token/non-java/client/mechanisms/pwd/windows/pwmech.def @@ -0,0 +1,10 @@ +LIBRARY PWMECH +DESCRIPTION 'CASA PW Authentication Mechanism Library.' + + +EXPORTS +; DllRegisterServer PRIVATE +; DllUnregisterServer PRIVATE +; DllGetClassObject PRIVATE + GetAuthTokenInterface PRIVATE +; DllCanUnloadNow PRIVATE \ No newline at end of file diff --git a/CASA-auth-token/non-java/client/test/CASA_Auth.cpp b/CASA-auth-token/non-java/client/test/CASA_Auth.cpp new file mode 100644 index 00000000..378da8ef --- /dev/null +++ b/CASA-auth-token/non-java/client/test/CASA_Auth.cpp @@ -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 + * + ***********************************************************************/ + +#include +#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; +} + + diff --git a/CASA-auth-token/non-java/client/test/test.vcproj b/CASA-auth-token/non-java/client/test/test.vcproj new file mode 100644 index 00000000..b14c9a9f --- /dev/null +++ b/CASA-auth-token/non-java/client/test/test.vcproj @@ -0,0 +1,142 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CASA-auth-token/non-java/client/util.c b/CASA-auth-token/non-java/client/util.c new file mode 100644 index 00000000..b93a5508 --- /dev/null +++ b/CASA-auth-token/non-java/client/util.c @@ -0,0 +1,321 @@ +/*********************************************************************** + * + * Copyright (C) 2006 Novell, Inc. All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, Novell, Inc. + * + * To contact Novell about this file by physical or electronic mail, + * you may find current contact information at www.novell.com. + * + * Author: Juan Carlos Luciani + * + ***********************************************************************/ + +//===[ Include files ]===================================================== + +#include "internal.h" + +//===[ Type definitions ]================================================== + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + +// Tables for Base64 encoding and decoding +static const int8_t g_Base64[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +static const uint8_t g_Expand64[256] = +{ + /* ASCII table */ + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64, + 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64, + 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 +}; + + +//++======================================================================= +CasaStatus +EncodeData( + IN const void *pData, + IN const int32_t dataLen, + INOUT char **ppEncodedData, + INOUT int32_t *pEncodedDataLen) +// +// Arguments: +// +// Returns: +// +// Description: +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus; + int encodedSize; + + char *pTmp; + + DbgTrace(3, "-EncodeData- Start\n", 0); + + // Determine the encoded size and allocate a buffer to hold the encoded data + encodedSize = ((dataLen * 4 + 2) / 3) - (dataLen % 3 ) + 4; + pTmp = (char*) malloc(encodedSize); + *ppEncodedData = pTmp; + if (*ppEncodedData) + { + uint8_t *pOut, *pIn; + int i; + + // Setup pointers to move through the buffers + pIn = (uint8_t*) pData; + pOut = (uint8_t*) *ppEncodedData; + + // Perform the encoding + for (i = 0; i < dataLen - 2; i += 3) + { + *pOut++ = g_Base64[(pIn[i] >> 2) & 0x3F]; + *pOut++ = g_Base64[((pIn[i] & 0x3) << 4) | + ((int32_t)(pIn[i + 1] & 0xF0) >> 4)]; + *pOut++ = g_Base64[((pIn[i + 1] & 0xF) << 2) | + ((int32_t)(pIn[i + 2] & 0xC0) >> 6)]; + *pOut++ = g_Base64[pIn[i + 2] & 0x3F]; + } + if (i < dataLen) + { + *pOut++ = g_Base64[(pIn[i] >> 2) & 0x3F]; + if (i == (dataLen - 1)) + { + *pOut++ = g_Base64[((pIn[i] & 0x3) << 4)]; + *pOut++ = '='; + } + else + { + *pOut++ = g_Base64[((pIn[i] & 0x3) << 4) | + ((int32_t)(pIn[i + 1] & 0xF0) >> 4)]; + *pOut++ = g_Base64[((pIn[i + 1] & 0xF) << 2)]; + } + *pOut++ = '='; + } + *pOut++ = '\0'; + + // Return the encoded data length + *pEncodedDataLen = (int32_t)(pOut - (uint8_t*)*ppEncodedData); + + // Success + retStatus = CASA_STATUS_SUCCESS; + } + else + { + DbgTrace(0, "-EncodeData- Buffer allocation failure\n", 0); + + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + + DbgTrace(3, "-EncodeData- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +CasaStatus +DecodeData( + IN const char *pEncodedData, + IN const int32_t encodedDataLen, // Does not include NULL terminator + INOUT void **ppData, + INOUT int32_t *pDataLen) +// +// Arguments: +// +// Returns: +// +// Description: +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus; + int i, j; + int decodedSize; + + DbgTrace(3, "-DecodeData- Start\n", 0); + + // Determine the decoded size + for (i = 0, j = 0; i < encodedDataLen; i++) + if (g_Expand64[((uint8_t*) pEncodedData)[i]] < 64) + j++; + decodedSize = (j * 3 + 3) / 4; + + // Allocate buffer to hold the decoded data + *ppData = malloc(decodedSize); + if (*ppData) + { + bool endReached = false; + uint8_t c0, c1, c2, c3; + uint8_t *p, *q; + + // Initialize parameters that will be used during the decode operation + c0 = c1 = c2 = c3 = 0; + p = (uint8_t*) pEncodedData; + q = (uint8_t*) *ppData; + + // Decode the data + // + // Loop through the data, piecing back information. Any newlines, and/or + // carriage returns need to be skipped. + while (j > 4) + { + while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p))) + p++; + if (64 == g_Expand64[*p]) + { + endReached = true; + break; + } + c0 = *(p++); + + while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p))) + p++; + if (64 == g_Expand64[*p]) + { + *(q++) = (uint8_t)(g_Expand64[c0] << 2); + j--; + endReached = true; + break; + } + c1 = *(p++); + + while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p))) + p++; + if (64 == g_Expand64[*p]) + { + *(q++) = (uint8_t)(g_Expand64[c0] << 2 | g_Expand64[c1] >> 4); + *(q++) = (uint8_t)(g_Expand64[c1] << 4); + j -= 2; + endReached = true; + break; + } + c2 = *(p++); + + while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p))) + p++; + if (64 == g_Expand64[*p]) + { + *(q++) = (uint8_t)(g_Expand64[c0] << 2 | g_Expand64[c1] >> 4); + *(q++) = (uint8_t)(g_Expand64[c1] << 4 | g_Expand64[c2] >> 2); + *(q++) = (uint8_t)(g_Expand64[c2] << 6); + j -= 3; + endReached = true; + break; + } + c3 = *(p++); + + *(q++) = (uint8_t)(g_Expand64[c0] << 2 | g_Expand64[c1] >> 4); + *(q++) = (uint8_t)(g_Expand64[c1] << 4 | g_Expand64[c2] >> 2); + *(q++) = (uint8_t)(g_Expand64[c2] << 6 | g_Expand64[c3]); + j -= 4; + } + if (!endReached) + { + if (j > 1) + *(q++) = (uint8_t)(g_Expand64[*p] << 2 | g_Expand64[p[1]] >> 4); + if (j > 2) + *(q++) = (uint8_t)(g_Expand64[p[1]] << 4 | g_Expand64[p[2]] >> 2); + if (j > 3) + *(q++) = (uint8_t)(g_Expand64[p[2]] << 6 | g_Expand64[p[3]]); + } + + // Return the length of the decoded data + *pDataLen = (int32_t)(q - (uint8_t*)*ppData); + + // Success + retStatus = CASA_STATUS_SUCCESS; + } + else + { + DbgTrace(0, "-DecodeData- Buffer allocation failure\n", 0); + + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + + DbgTrace(3, "-DecodeData- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +int +dtoul( + IN const char *cp, + IN const int len) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + int n = 0; + int i; + + DbgTrace(2, "-dtoul- Start\n", 0); + + for (i = 0; i < len; i++, cp++) + { + // Verify that we are dealing with a valid digit + if (*cp >= '0' && *cp <= '9') + { + n = 10 * n + (*cp - '0'); + } + else + { + DbgTrace(0, "-dtoul- Found invalid digit\n", 0); + break; + } + } + + DbgTrace(2, "-dtoul- End, result = %d\n", n); + + return n; +} + + +//++======================================================================= +//++======================================================================= +//++======================================================================= + diff --git a/CASA-auth-token/non-java/client/windows/authtoken.def b/CASA-auth-token/non-java/client/windows/authtoken.def new file mode 100644 index 00000000..1862e07e --- /dev/null +++ b/CASA-auth-token/non-java/client/windows/authtoken.def @@ -0,0 +1,10 @@ +LIBRARY AUTHTOKEN +DESCRIPTION 'CASA Authentication Token Library.' + + +EXPORTS +; DllRegisterServer PRIVATE +; DllUnregisterServer PRIVATE +; DllGetClassObject PRIVATE + ObtainAuthToken PRIVATE +; DllCanUnloadNow PRIVATE \ No newline at end of file diff --git a/CASA-auth-token/non-java/client/windows/dllsup.c b/CASA-auth-token/non-java/client/windows/dllsup.c new file mode 100644 index 00000000..c30b3cb2 --- /dev/null +++ b/CASA-auth-token/non-java/client/windows/dllsup.c @@ -0,0 +1,132 @@ +/*********************************************************************** + * + * Copyright (C) 2006 Novell, Inc. All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, Novell, Inc. + * + * To contact Novell about this file by physical or electronic mail, + * you may find current contact information at www.novell.com. + * + * Author: Juan Carlos Luciani + * + ***********************************************************************/ + +//===[ Include files ]===================================================== + +#include "internal.h" + +//===[ External data ]===================================================== + +//===[ Manifest constants ]================================================ + +//===[ Type definitions ]================================================== + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + +UINT32 g_ulCount = 0; +UINT32 g_ulLock = 0; +HANDLE g_hModule; + + +//++======================================================================= +BOOL APIENTRY DllMain( + HANDLE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +//=======================================================================-- +{ + BOOL retStatus = TRUE; + + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + { + g_hModule = hModule; + + // Initialize the library + if (Initialize() != 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); +} + +//========================================================================= +//========================================================================= + diff --git a/CASA-auth-token/non-java/client/windows/platform.c b/CASA-auth-token/non-java/client/windows/platform.c new file mode 100644 index 00000000..1003ece0 --- /dev/null +++ b/CASA-auth-token/non-java/client/windows/platform.c @@ -0,0 +1,665 @@ +/*********************************************************************** + * + * Copyright (C) 2006 Novell, Inc. All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, Novell, Inc. + * + * To contact Novell about this file by physical or electronic mail, + * you may find current contact information at www.novell.com. + * + * Author: Juan Carlos Luciani + * + ***********************************************************************/ + +//===[ Include files ]===================================================== + +#include "internal.h" + +//===[ Type definitions ]================================================== + +// +// Normalized Host Name Cache Entry definition +// +typedef struct _NormalizedHostNameCacheEntry +{ + LIST_ENTRY listEntry; + char *pHostName; + char *pNormalizedHostName; + int buffLengthRequired; + +} NormalizedHostNameCacheEntry, *PNormalizedHostNameCacheEntry; + + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + +// Normalized host name cache list head +static +LIST_ENTRY normalizedHostNameCacheListHead; + +// Synchronization mutex for the normalized host name cache +static +HANDLE hNormalizedHostNameCacheMutex; + +// Authentication mechanism configuration file folder +char mechConfigFolder[] = "\\Program Files\\Novell\\Casa\\Etc\\Auth\\Mechanisms"; + +// Synchronization mutex for the dll initialization +static +HANDLE g_hInitializationMutex; + +// Path separator +char pathCharString[] = "\\"; + +//++======================================================================= +CasaStatus +CreateUserMutex( + HANDLE *phMutex + ) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus = CASA_STATUS_SUCCESS; + char *pUsername = NULL; + DWORD nameLength = 0; + + DbgTrace(1, "-CreateUserMutex- Start\n", 0); + + // Get the size of the buffer required to obtain the user name + GetUserName(pUsername, &nameLength); + if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) + { + // Allocate buffer to hold the user name + pUsername = (char*) malloc(nameLength); + if (pUsername) + { + // Get the name of the user + if (GetUserName(pUsername, &nameLength)) + { + SECURITY_ATTRIBUTES mutexAttributes; + char mutexName[256]; + + // Now lets create a global semaphore for the + // user and allow its handle to be inherited. + mutexAttributes.nLength = sizeof(mutexAttributes); + mutexAttributes.lpSecurityDescriptor = NULL; + mutexAttributes.bInheritHandle = TRUE; + if (sprintf(mutexName, "Global\\CASA_Auth_Mutex_%s", pUsername) != -1) + { + *phMutex = CreateMutex(&mutexAttributes, + FALSE, + mutexName); + if (*phMutex == NULL) + { + DbgTrace(0, "-CreateUserMutex- 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- Unexpected GetUserName error, error = %d\n", GetLastError()); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_UNSUCCESSFUL); + } + + DbgTrace(1, "-CreateUserMutex- End, retStatus\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +void +AcquireUserMutex( + HANDLE hMutex + ) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + DbgTrace(2, "-AcquireUserMutex- Start\n", 0); + + WaitForSingleObject(hMutex, INFINITE); + + DbgTrace(2, "-AcquireUserMutex- End\n", 0); +} + + +//++======================================================================= +void +ReleaseUserMutex( + HANDLE hMutex + ) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + DbgTrace(2, "-ReleaseUserMutex- Start\n", 0); + + if (ReleaseMutex(hMutex) == 0) + { + DbgTrace(0, "-ReleaseUserMutex- ReleaseMutex failed, error = %d\n", GetLastError()); + } + + DbgTrace(2, "-ReleaseUserMutex- End\n", 0); +} + + +//++======================================================================= +void +DestroyUserMutex( + HANDLE hMutex + ) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + DbgTrace(2, "-DestroyUserMutex- Start\n", 0); + + if (CloseHandle(hMutex) == 0) + { + DbgTrace(0, "-DestroyUserMutex- CloseHandle failed, error = %d\n", GetLastError()); + } + + DbgTrace(2, "-DestroyUserMutex- End\n", 0); +} + + +//++======================================================================= +CasaStatus +CreateInitializationMutex(void) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + int retStatus = -1; + + + DbgTrace(2, "-CreateInitializationMutex- Start\n", 0); + + // Create a cache mutex only applicable to the current process + g_hInitializationMutex = CreateMutex(NULL, FALSE, NULL); + + if (g_hInitializationMutex != NULL) + { + retStatus = CASA_STATUS_SUCCESS; + } + + DbgTrace(2, "-CreateInitializationMutex- End\n", 0); + + return retStatus; +} + + +//++======================================================================= +void +AcquireInitializationMutex(void) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + DbgTrace(2, "-AcquireInitializationMutex- Start\n", 0); + + WaitForSingleObject(g_hInitializationMutex, INFINITE); + + DbgTrace(2, "-AcquireInitializationMutex- End\n", 0); +} + + +//++======================================================================= +void +ReleaseInitializationMutex(void) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + DbgTrace(2, "-ReleaseInitializationMutex- Start\n", 0); + + if (ReleaseMutex(g_hInitializationMutex) == 0) + { + DbgTrace(0, "-ReleaseInitializationMutex- ReleaseMutex failed, error\n", 0); + } + + DbgTrace(2, "-ReleaseInitializationMutex- End\n", 0); +} + + +//++======================================================================= +LIB_HANDLE +OpenLibrary( + IN char *pFileName) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + LIB_HANDLE libHandle; + + + DbgTrace(1, "-OpenLibrary- Start\n", 0); + + libHandle = LoadLibrary(pFileName); + if (libHandle == NULL) + { + DbgTrace(0, "-OpenLibrary- Not able to load library, error = %d\n", GetLastError()); + } + + DbgTrace(1, "-OpenLibrary- End, handle = %08X\n", libHandle); + + return libHandle; +} + + +//++======================================================================= +void +CloseLibrary( + IN LIB_HANDLE libHandle) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + DbgTrace(1, "-CloseLibrary- Start\n", 0); + + FreeLibrary(libHandle); + + DbgTrace(1, "-CloseLibrary- End\n", 0); +} + + +//++======================================================================= +void* +GetFunctionPtr( + IN LIB_HANDLE libHandle, + IN char *pFunctionName) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + void *pFuncPtr; + + + DbgTrace(1, "-GetFunctionPtr- Start\n", 0); + + pFuncPtr = GetProcAddress(libHandle, pFunctionName); + if (pFuncPtr == NULL) + { + DbgTrace(0, "-GetFunctionPtr- Not able to obtain func ptr, error = %d\n", GetLastError()); + } + + DbgTrace(1, "-GetFunctionPtr- End, pFuncPtr = %08X\n", pFuncPtr); + + return pFuncPtr; +} + + +//++======================================================================= +char* +NormalizeHostName( + IN const char *pHostName) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + char *pNormalizedName = NULL; + LIST_ENTRY *pListEntry; + NormalizedHostNameCacheEntry *pEntry = NULL; + + + DbgTrace(1, "-NormalizeHostName- Start\n", 0); + + // Obtain our synchronization mutex + WaitForSingleObject(hNormalizedHostNameCacheMutex, INFINITE); + + // First try to find an entry in the normalized host name cache + // for the host name provided. + pListEntry = normalizedHostNameCacheListHead.Flink; + while (pListEntry != &normalizedHostNameCacheListHead) + { + // Get pointer to the entry + pEntry = CONTAINING_RECORD(pListEntry, NormalizedHostNameCacheEntry, listEntry); + + // Check if the entry is for the host name + if (strcmp(pHostName, pEntry->pHostName) == 0) + { + // This entry corresponds to the given host name + break; + } + else + { + // The entry does not correspond to the given host name + pEntry = NULL; + } + + // Advance to the next entry + pListEntry = pListEntry->Flink; + } + + // Check if we found an entry in our cache for the given host name + if (pEntry) + { + // Entry found, obtain the normalized name from it. + pNormalizedName = (char*) malloc(pEntry->buffLengthRequired); + if (pNormalizedName) + { + // Copy the normalized name onto the allocated buffer + strcpy(pNormalizedName, pEntry->pNormalizedHostName); + } + else + { + DbgTrace(0, "-NormalizeHostName- Buffer allocation error\n", 0); + } + } + else + { + // An entry was not found in our cache, create one. + pEntry = (NormalizedHostNameCacheEntry*) malloc(sizeof(NormalizedHostNameCacheEntry)); + if (pEntry) + { + // Zero the entry + memset(pEntry, 0, sizeof(*pEntry)); + + // Allocate a buffer to hold the host name in the entry + pEntry->pHostName = (char*) malloc(strlen(pHostName) + 1); + if (pEntry->pHostName) + { + struct hostent *pLookupResult; + struct sockaddr_in sockAddr = {0}; + + // Copy the host name given into the allocated buffer + strcpy(pEntry->pHostName, pHostName); + + // Now try to resolve the normalized name + pLookupResult = gethostbyname(pHostName); + if (pLookupResult && pLookupResult->h_addrtype == AF_INET) + { + char dnsHostName[NI_MAXHOST]; + + // Set up a sockaddr structure + sockAddr.sin_family = AF_INET; + sockAddr.sin_addr.S_un.S_addr = *((int*) pLookupResult->h_addr_list[0]); + + // Now try to resolve the name using DNS + if (getnameinfo((const struct sockaddr*) &sockAddr, + sizeof(sockAddr), + dnsHostName, + sizeof(dnsHostName), + NULL, + 0, + NI_NAMEREQD) == 0) + { + // We resolved the address to a DNS name, use it as the normalized name. + pEntry->buffLengthRequired = (int) strlen(dnsHostName) + 1; + pEntry->pNormalizedHostName = (char*) malloc(pEntry->buffLengthRequired); + if (pEntry->pNormalizedHostName) + { + // Copy the dns name + strcpy(pEntry->pNormalizedHostName, dnsHostName); + } + else + { + DbgTrace(0, "-NormalizeHostName- Buffer allocation error\n", 0); + } + } + else + { + DbgTrace(0, "-NormalizeHostName- getnameInfo failed, error %d\n", WSAGetLastError()); + + // Not able to resolve the name in DNS, just use the host name as + // the normalized name. + pEntry->buffLengthRequired = (int) strlen(pHostName) + 1; + pEntry->pNormalizedHostName = (char*) malloc(pEntry->buffLengthRequired); + if (pEntry->pNormalizedHostName) + { + // Copy the host name + strcpy(pEntry->pNormalizedHostName, pHostName); + } + else + { + DbgTrace(0, "-NormalizeHostName- Buffer allocation error\n", 0); + } + } + } + else + { + DbgTrace(0, "-NormalizeHostName- Name resolution failed, error = %d\n", WSAGetLastError()); + } + } + else + { + DbgTrace(0, "-NormalizeHostName- Buffer allocation error\n", 0); + + // Free the space allocated for the entry + free(pEntry); + } + + // Proceed based on whether or not we normalized the name + if (pEntry->pNormalizedHostName) + { + // The name was normalized, save the entry in our cache. + InsertHeadList(&normalizedHostNameCacheListHead, &pEntry->listEntry); + + // Return the normalized name present in the entry + pNormalizedName = (char*) malloc(pEntry->buffLengthRequired); + if (pNormalizedName) + { + // Copy the normalized name onto the allocated buffer + strcpy(pNormalizedName, pEntry->pNormalizedHostName); + } + else + { + DbgTrace(0, "-NormalizeHostName- Buffer allocation error\n", 0); + } + } + else + { + // The host name was not normalized, free allocated resources. + if (pEntry->pHostName) + free(pEntry->pHostName); + free(pEntry); + } + } + else + { + DbgTrace(0, "-NormalizeHostName- Buffer allocation error\n", 0); + } + } + + // Release our synchronization mutex + if (ReleaseMutex(hNormalizedHostNameCacheMutex) == 0) + { + DbgTrace(0, "-NormalizeHostName- ReleaseMutex failed, error\n", 0); + } + + DbgTrace(1, "-NormalizeHostName- End, pNormalizedName = %08X\n", pNormalizedName); + + return pNormalizedName; +} + + +//++======================================================================= +CasaStatus +InitializeHostNameNormalization(void) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_UNSUCCESSFUL); + int winsockStartupResult; + WSADATA winsockData; + + DbgTrace(1, "-InitializeHostNameNormalization- Start\n", 0); + + // Initialize winsock + if ((winsockStartupResult = WSAStartup(MAKEWORD(2,2), &winsockData)) == 0) + { + // Initialize the cache list head + InitializeListHead(&normalizedHostNameCacheListHead); + + // Create a cache mutex only applicable to the current process + hNormalizedHostNameCacheMutex = CreateMutex(NULL, + FALSE, + NULL); + if (hNormalizedHostNameCacheMutex != NULL) + { + retStatus = CASA_STATUS_SUCCESS; + } + else + { + DbgTrace(0, "-InitializeHostNameNormalization- CreateMutex failed, error = %d\n", GetLastError()); + } + } + else + { + DbgTrace(0, "-InitializeHostNameNormalization- WSAStartup failed, error = %d\n", winsockStartupResult); + } + + DbgTrace(1, "-InitializeHostNameNormalization- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +//++======================================================================= +//++======================================================================= + diff --git a/CASA-auth-token/non-java/client/windows/platform.h b/CASA-auth-token/non-java/client/windows/platform.h new file mode 100644 index 00000000..c40accce --- /dev/null +++ b/CASA-auth-token/non-java/client/windows/platform.h @@ -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 + * + ***********************************************************************/ + + +//===[ Include files ]===================================================== + +#include +#include +#include +#include +#include +#include +#include + +//===[ Type definitions ]================================================== + +#ifndef CONTAINING_RECORD +#define CONTAINING_RECORD(address, type, field) ((type *)( \ + (char*)(address) - \ + (char*)(&((type *)0)->field))) +#endif + +// +// DbgTrace macro define +// +//#define DbgTrace(LEVEL, X, Y) { \ +//char printBuff[256]; \ +// if (LEVEL == 0 || DebugLevel >= LEVEL) \ +// { \ +// _snprintf(printBuff, sizeof(printBuff), X, Y); \ +// printf("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; + int status; + DWORD creationTime; + DWORD expirationTime; + BOOL doesNotExpire; +// char *pHostName; +// char *pCacheKeyName; + char token[1]; + +} 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 ]=============================================== + +//========================================================================= + diff --git a/CASA-auth-token/non-java/client/windows/rpc.c b/CASA-auth-token/non-java/client/windows/rpc.c new file mode 100644 index 00000000..96b4716f --- /dev/null +++ b/CASA-auth-token/non-java/client/windows/rpc.c @@ -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 + * + ***********************************************************************/ + + +//===[ 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; +} + + +//++======================================================================= +//++======================================================================= +//++======================================================================= +