Separated the non-java project into client and server projects
in order to better support distributions that target desktops. This commit completes the client project setup.
This commit is contained in:
		
							
								
								
									
										69
									
								
								CASA-auth-token/client/lib/windows/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								CASA-auth-token/client/lib/windows/Makefile.am
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,69 @@ | ||||
| ####################################################################### | ||||
| # | ||||
| #  Copyright (C) 2004 Novell, Inc. | ||||
| # | ||||
| #  This program is free software; you can redistribute it and/or | ||||
| #  modify it under the terms of the GNU General Public | ||||
| #  License as published by the Free Software Foundation; either | ||||
| #  version 2 of the License, or (at your option) any later version. | ||||
| # | ||||
| #  This program is distributed in the hope that it will be useful, | ||||
| #  but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
| #  General Public License for more details. | ||||
| # | ||||
| #  You should have received a copy of the GNU General Public | ||||
| #  License along with this program; if not, write to the Free | ||||
| #  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||||
| # | ||||
| #  Author: Greg Richardson <grichardson@novell.com> | ||||
| # | ||||
| ####################################################################### | ||||
|  | ||||
| SUBDIRS = | ||||
|  | ||||
| DIST_SUBDIRS = | ||||
|  | ||||
| EXTRA_DIST = client.vcproj ../*.c *.c *.h *.def | ||||
|  | ||||
| if DEBUG | ||||
| TARGET_CFG = Debug | ||||
| else | ||||
| TARGET_CFG = Release | ||||
| endif | ||||
|  | ||||
| PACKAGE = client | ||||
| TARGET_FILE = authtoken.dll | ||||
| LOG_FILE = $(PACKAGE).log | ||||
|  | ||||
| all-am: $(TARGET_FILE) | ||||
|  | ||||
| .PHONY: $TARGET_FILE) devenv | ||||
|  | ||||
| devenv: | ||||
| 	@if ! test -x "$(VSINSTALLDIR)/devenv.exe"; then echo "Error: Microsoft Visual Studio .NET is currently required to build MSI and MSM packages"; exit 1; fi | ||||
|  | ||||
| $(TARGET_FILE): devenv | ||||
| 	@rm -f $(LOG_FILE) $@ | ||||
| 	@CMD='"$(VSINSTALLDIR)/devenv.exe" ../../auth.sln /build $(TARGET_CFG) /project $(PACKAGE) /out $(LOG_FILE)'; \ | ||||
| 	echo $$CMD; \ | ||||
| 	if eval $$CMD; then \ | ||||
| 		ls -l $(TARGET_CFG)/$(TARGET_FILE); \ | ||||
| 	else \ | ||||
| 		grep -a "ERROR:" $(LOG_FILE); \ | ||||
| 	fi | ||||
| 	 | ||||
| package-clean clean-local: | ||||
| 	rm -rf  Release/* Release Debug/* Debug*/Release */Debug *.log *.suo | ||||
|  | ||||
| clean: | ||||
| 	rm -rf  Release/* Release Debug/* Debug */Release */Debug *.log *.suo | ||||
|  | ||||
| distclean-local: package-clean | ||||
| 	rm -f Makefile  | ||||
|  | ||||
| maintainer-clean-local: | ||||
| 	rm -f Makefile.in | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										11
									
								
								CASA-auth-token/client/lib/windows/authtoken.def
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								CASA-auth-token/client/lib/windows/authtoken.def
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| LIBRARY         AUTHTOKEN | ||||
| DESCRIPTION     'CASA Authentication Token Library.' | ||||
|  | ||||
|  | ||||
| EXPORTS | ||||
| ;                DllRegisterServer   PRIVATE | ||||
| ;                DllUnregisterServer PRIVATE | ||||
| ;                DllGetClassObject   PRIVATE | ||||
|                 ObtainAuthToken     PRIVATE         | ||||
|                 ObtainAuthTokenEx   PRIVATE         | ||||
| ;               DllCanUnloadNow     PRIVATE   | ||||
							
								
								
									
										224
									
								
								CASA-auth-token/client/lib/windows/client.vcproj
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										224
									
								
								CASA-auth-token/client/lib/windows/client.vcproj
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,224 @@ | ||||
| <?xml version="1.0" encoding="Windows-1252"?> | ||||
| <VisualStudioProject | ||||
| 	ProjectType="Visual C++" | ||||
| 	Version="7.10" | ||||
| 	Name="client" | ||||
| 	ProjectGUID="{7BD9A5DB-DE7D-40B7-A397-04182DC2F632}" | ||||
| 	RootNamespace="client" | ||||
| 	Keyword="Win32Proj"> | ||||
| 	<Platforms> | ||||
| 		<Platform | ||||
| 			Name="Win32"/> | ||||
| 	</Platforms> | ||||
| 	<Configurations> | ||||
| 		<Configuration | ||||
| 			Name="Debug|Win32" | ||||
| 			OutputDirectory="$(SolutionDir)client\windows\$(ConfigurationName)" | ||||
| 			IntermediateDirectory="$(SolutionDir)client\windows\$(ConfigurationName)" | ||||
| 			ConfigurationType="2" | ||||
| 			CharacterSet="2"> | ||||
| 			<Tool | ||||
| 				Name="VCCLCompilerTool" | ||||
| 				AdditionalOptions="/D "XML_STATIC"" | ||||
| 				Optimization="0" | ||||
| 				AdditionalIncludeDirectories=".;..\;..\..\include;..\..\include\windows;"\Program Files\novell\casa\include";"C:\Dev\Expat-2.0.0\Source\lib"" | ||||
| 				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" | ||||
| 				MinimalRebuild="TRUE" | ||||
| 				BasicRuntimeChecks="3" | ||||
| 				RuntimeLibrary="5" | ||||
| 				UsePrecompiledHeader="0" | ||||
| 				WarningLevel="3" | ||||
| 				Detect64BitPortabilityProblems="TRUE" | ||||
| 				DebugInformationFormat="4"/> | ||||
| 			<Tool | ||||
| 				Name="VCCustomBuildTool"/> | ||||
| 			<Tool | ||||
| 				Name="VCLinkerTool" | ||||
| 				IgnoreImportLibrary="FALSE" | ||||
| 				AdditionalOptions="/EXPORT:ObtainAuthToken /EXPORT:ObtainAuthTokenEx" | ||||
| 				AdditionalDependencies="ws2_32.lib winhttp.lib libexpatml.lib micasa.lib shlwapi.lib" | ||||
| 				OutputFile="$(OutDir)/authtoken.dll" | ||||
| 				LinkIncremental="1" | ||||
| 				AdditionalLibraryDirectories=""\Program Files\Novell\CASA\lib";"C:\Dev\Expat-2.0.0\StaticLibs"" | ||||
| 				GenerateDebugInformation="TRUE" | ||||
| 				ProgramDatabaseFile="$(OutDir)/client.pdb" | ||||
| 				SubSystem="0" | ||||
| 				ImportLibrary="$(SolutionDir)client\windows/$(TargetName).lib" | ||||
| 				TargetMachine="1"/> | ||||
| 			<Tool | ||||
| 				Name="VCMIDLTool"/> | ||||
| 			<Tool | ||||
| 				Name="VCPostBuildEventTool" | ||||
| 				CommandLine="mkdir \"Program Files"\novell\ | ||||
| mkdir \"Program Files"\novell\casa | ||||
| mkdir \"Program Files"\novell\casa\lib\ | ||||
| copy $(OutDir)\authtoken.dll \"Program Files"\novell\casa\lib\authtoken.dll | ||||
| copy $(SolutionDir)\client\windows\authtoken.lib \"Program Files"\novell\casa\lib\authtoken.lib | ||||
| "/> | ||||
| 			<Tool | ||||
| 				Name="VCPreBuildEventTool"/> | ||||
| 			<Tool | ||||
| 				Name="VCPreLinkEventTool"/> | ||||
| 			<Tool | ||||
| 				Name="VCResourceCompilerTool"/> | ||||
| 			<Tool | ||||
| 				Name="VCWebServiceProxyGeneratorTool"/> | ||||
| 			<Tool | ||||
| 				Name="VCXMLDataGeneratorTool"/> | ||||
| 			<Tool | ||||
| 				Name="VCWebDeploymentTool"/> | ||||
| 			<Tool | ||||
| 				Name="VCManagedWrapperGeneratorTool"/> | ||||
| 			<Tool | ||||
| 				Name="VCAuxiliaryManagedWrapperGeneratorTool"/> | ||||
| 		</Configuration> | ||||
| 		<Configuration | ||||
| 			Name="Release|Win32" | ||||
| 			OutputDirectory="$(SolutionDir)client\windows\$(ConfigurationName)" | ||||
| 			IntermediateDirectory="$(SolutionDir)client\windows\$(ConfigurationName)" | ||||
| 			ConfigurationType="2" | ||||
| 			CharacterSet="2"> | ||||
| 			<Tool | ||||
| 				Name="VCCLCompilerTool" | ||||
| 				AdditionalOptions="/D "XML_STATIC"" | ||||
| 				AdditionalIncludeDirectories=".;..\;..\..\include;..\..\include\windows;"\Program Files\novell\casa\include";"C:\Dev\Expat-2.0.0\Source\lib"" | ||||
| 				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" | ||||
| 				RuntimeLibrary="4" | ||||
| 				UsePrecompiledHeader="0" | ||||
| 				WarningLevel="3" | ||||
| 				Detect64BitPortabilityProblems="TRUE" | ||||
| 				DebugInformationFormat="3"/> | ||||
| 			<Tool | ||||
| 				Name="VCCustomBuildTool"/> | ||||
| 			<Tool | ||||
| 				Name="VCLinkerTool" | ||||
| 				AdditionalOptions="/EXPORT:ObtainAuthToken /EXPORT:ObtainAuthTokenEx" | ||||
| 				AdditionalDependencies="ws2_32.lib winhttp.lib libexpatml.lib micasa.lib shlwapi.lib" | ||||
| 				OutputFile="$(OutDir)/authtoken.dll" | ||||
| 				LinkIncremental="1" | ||||
| 				AdditionalLibraryDirectories=""\Program Files\Novell\CASA\lib";"C:\Dev\Expat-2.0.0\StaticLibs"" | ||||
| 				GenerateDebugInformation="TRUE" | ||||
| 				SubSystem="0" | ||||
| 				OptimizeReferences="2" | ||||
| 				EnableCOMDATFolding="2" | ||||
| 				ImportLibrary="$(SolutionDir)client\windows\$(TargetName).lib" | ||||
| 				TargetMachine="1"/> | ||||
| 			<Tool | ||||
| 				Name="VCMIDLTool"/> | ||||
| 			<Tool | ||||
| 				Name="VCPostBuildEventTool" | ||||
| 				CommandLine="mkdir \"Program Files"\novell\ | ||||
| mkdir \"Program Files"\novell\casa | ||||
| mkdir \"Program Files"\novell\casa\lib\ | ||||
| copy $(OutDir)\authtoken.dll \"Program Files"\novell\casa\lib\authtoken.dll | ||||
| copy $(SolutionDir)\client\windows\authtoken.lib \"Program Files"\novell\casa\lib\authtoken.lib | ||||
| "/> | ||||
| 			<Tool | ||||
| 				Name="VCPreBuildEventTool"/> | ||||
| 			<Tool | ||||
| 				Name="VCPreLinkEventTool"/> | ||||
| 			<Tool | ||||
| 				Name="VCResourceCompilerTool"/> | ||||
| 			<Tool | ||||
| 				Name="VCWebServiceProxyGeneratorTool"/> | ||||
| 			<Tool | ||||
| 				Name="VCXMLDataGeneratorTool"/> | ||||
| 			<Tool | ||||
| 				Name="VCWebDeploymentTool"/> | ||||
| 			<Tool | ||||
| 				Name="VCManagedWrapperGeneratorTool"/> | ||||
| 			<Tool | ||||
| 				Name="VCAuxiliaryManagedWrapperGeneratorTool"/> | ||||
| 		</Configuration> | ||||
| 	</Configurations> | ||||
| 	<References> | ||||
| 	</References> | ||||
| 	<Files> | ||||
| 		<Filter | ||||
| 			Name="Source Files" | ||||
| 			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" | ||||
| 			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"> | ||||
| 			<File | ||||
| 				RelativePath="..\authmech.c"> | ||||
| 			</File> | ||||
| 			<File | ||||
| 				RelativePath="..\authmsg.c"> | ||||
| 			</File> | ||||
| 			<File | ||||
| 				RelativePath="..\authpolicy.c"> | ||||
| 			</File> | ||||
| 			<File | ||||
| 				RelativePath=".\authtoken.def"> | ||||
| 			</File> | ||||
| 			<File | ||||
| 				RelativePath="..\cache.c"> | ||||
| 			</File> | ||||
| 			<File | ||||
| 				RelativePath="..\client.conf"> | ||||
| 			</File> | ||||
| 			<File | ||||
| 				RelativePath="..\config.c"> | ||||
| 			</File> | ||||
| 			<File | ||||
| 				RelativePath=".\dllsup.c"> | ||||
| 			</File> | ||||
| 			<File | ||||
| 				RelativePath="..\engine.c"> | ||||
| 			</File> | ||||
| 			<File | ||||
| 				RelativePath="..\getpolicymsg.c"> | ||||
| 			</File> | ||||
| 			<File | ||||
| 				RelativePath="..\gettokenmsg.c"> | ||||
| 			</File> | ||||
| 			<File | ||||
| 				RelativePath="..\invalidcert.c"> | ||||
| 			</File> | ||||
| 			<File | ||||
| 				RelativePath=".\platform.c"> | ||||
| 			</File> | ||||
| 			<File | ||||
| 				RelativePath=".\rpc.c"> | ||||
| 			</File> | ||||
| 			<File | ||||
| 				RelativePath="..\util.c"> | ||||
| 			</File> | ||||
| 		</Filter> | ||||
| 		<Filter | ||||
| 			Name="Header Files" | ||||
| 			Filter="h;hpp;hxx;hm;inl;inc;xsd" | ||||
| 			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"> | ||||
| 			<File | ||||
| 				RelativePath="..\..\include\casa_c_authtoken.h"> | ||||
| 			</File> | ||||
| 			<File | ||||
| 				RelativePath="..\..\include\windows\casa_c_authtoken_ex.h"> | ||||
| 			</File> | ||||
| 			<File | ||||
| 				RelativePath="..\config_if.h"> | ||||
| 			</File> | ||||
| 			<File | ||||
| 				RelativePath="..\internal.h"> | ||||
| 			</File> | ||||
| 			<File | ||||
| 				RelativePath="..\..\include\list_entry.h"> | ||||
| 			</File> | ||||
| 			<File | ||||
| 				RelativePath="..\mech_if.h"> | ||||
| 			</File> | ||||
| 			<File | ||||
| 				RelativePath=".\platform.h"> | ||||
| 			</File> | ||||
| 			<File | ||||
| 				RelativePath="..\..\include\proto.h"> | ||||
| 			</File> | ||||
| 		</Filter> | ||||
| 		<Filter | ||||
| 			Name="Resource Files" | ||||
| 			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" | ||||
| 			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"> | ||||
| 		</Filter> | ||||
| 	</Files> | ||||
| 	<Globals> | ||||
| 	</Globals> | ||||
| </VisualStudioProject> | ||||
							
								
								
									
										233
									
								
								CASA-auth-token/client/lib/windows/dllsup.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										233
									
								
								CASA-auth-token/client/lib/windows/dllsup.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,233 @@ | ||||
| /*********************************************************************** | ||||
|  *  | ||||
|  *  Copyright (C) 2006 Novell, Inc. All Rights Reserved. | ||||
|  * | ||||
|  *  This library is free software; you can redistribute it and/or | ||||
|  *  modify it under the terms of the GNU Lesser General Public | ||||
|  *  License as published by the Free Software Foundation; version 2.1 | ||||
|  *  of the License. | ||||
|  * | ||||
|  *  This library is distributed in the hope that it will be useful, | ||||
|  *  but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  *  Library Lesser General Public License for more details. | ||||
|  * | ||||
|  *  You should have received a copy of the GNU Lesser General Public | ||||
|  *  License along with this library; if not, Novell, Inc. | ||||
|  *  | ||||
|  *  To contact Novell about this file by physical or electronic mail,  | ||||
|  *  you may find current contact information at www.novell.com. | ||||
|  *  | ||||
|  *  Author: Juan Carlos Luciani <jluciani@novell.com> | ||||
|  * | ||||
|  ***********************************************************************/ | ||||
|  | ||||
| //===[ Include files ]===================================================== | ||||
|  | ||||
| #include "internal.h" | ||||
| #include <shlobj.h> | ||||
| #include <shlwapi.h> | ||||
| #include "casa_c_authtoken_ex.h" | ||||
|  | ||||
| //===[ External data ]===================================================== | ||||
| extern | ||||
| char  clientConfigFolderPartialPath[]; | ||||
|  | ||||
| extern | ||||
| char  mechConfigFolderPartialPath[]; | ||||
|  | ||||
| //===[ Manifest constants ]================================================ | ||||
|  | ||||
| //===[ Type definitions ]================================================== | ||||
|  | ||||
| //===[ Function prototypes ]=============================================== | ||||
|  | ||||
| //===[ Global variables ]================================================== | ||||
|  | ||||
| UINT32 g_ulCount  = 0; | ||||
| UINT32 g_ulLock = 0; | ||||
| HANDLE g_hModule; | ||||
| HANDLE g_hModuleMutex; | ||||
|  | ||||
|  | ||||
| //++======================================================================= | ||||
| CasaStatus SSCS_CALL | ||||
| ObtainAuthTokenEx( | ||||
|    IN    const char *pServiceName, | ||||
|    IN    const char *pHostName, | ||||
|    INOUT char *pAuthTokenBuf, | ||||
|    INOUT int *pAuthTokenBufLen, | ||||
|    IN    void *pCredStoreScope) | ||||
| // | ||||
| //  Arguments:  | ||||
| //    pServiceName - | ||||
| //       Pointer to NULL terminated string that contains the | ||||
| //       name of the service to which the client is trying to | ||||
| //       authenticate. | ||||
| //                | ||||
| //    pHostName - | ||||
| //       Pointer to NULL terminated string that contains the | ||||
| //       name of the host where resides the service to which the | ||||
| //       client is trying to authenticate. Note that the name | ||||
| //       can either be a DNS name or a dotted IP address. | ||||
| //                | ||||
| //    pAuthTokenBuf - | ||||
| //       Pointer to buffer that will receive the authentication | ||||
| //       token. The length of this buffer is specified by the | ||||
| //       pAuthTokenBufLen parameter. Note that the the authentication | ||||
| //       token will be in the form of a NULL terminated string. | ||||
| // | ||||
| //    pAuthTokenBufLen - | ||||
| //       Pointer to integer that contains the length of the | ||||
| //       buffer pointed at by pAuthTokenBuf. Upon return of the | ||||
| //       function, the integer will contain the actual length | ||||
| //       of the authentication token if the function successfully | ||||
| //       completes or the buffer length required if the function | ||||
| //       fails because the buffer pointed at by pAuthTokenBuf is | ||||
| //       not large enough. | ||||
| // | ||||
| //    pCredStoreScope - | ||||
| //       Pointer to CASA structure for scoping credential store access | ||||
| //       to specific users. This can only be leveraged by applications | ||||
| //       running in the context of System. | ||||
| //    | ||||
| // Returns: | ||||
| //    Casa Status | ||||
| //                            | ||||
| // Description: | ||||
| //    Get authentication token to authenticate user to specified | ||||
| //    service at host. The user is scoped using the info associated | ||||
| //    with the magic cookie. | ||||
| // | ||||
| // L2 | ||||
| //=======================================================================-- | ||||
| { | ||||
|    CasaStatus        retStatus; | ||||
|  | ||||
|    DbgTrace(1, "-ObtainAuthTokenEx- Start\n", 0); | ||||
|  | ||||
|    // Call our internal worker | ||||
|    retStatus = ObtainAuthTokenInt(pServiceName, | ||||
|                                   pHostName, | ||||
|                                   pAuthTokenBuf, | ||||
|                                   pAuthTokenBufLen, | ||||
|                                   pCredStoreScope); | ||||
|  | ||||
|    DbgTrace(1, "-ObtainAuthTokenEx- End, retStatus = %08X\n", retStatus); | ||||
|  | ||||
|    return retStatus; | ||||
| } | ||||
|  | ||||
|  | ||||
| //++======================================================================= | ||||
| BOOL APIENTRY DllMain( | ||||
|    HANDLE hModule, | ||||
|    DWORD  ul_reason_for_call, | ||||
|    LPVOID lpReserved    | ||||
|    ) | ||||
| //=======================================================================-- | ||||
| { | ||||
|    BOOL  retStatus = TRUE; | ||||
|    char  programFilesFolder[MAX_PATH]; | ||||
|  | ||||
|    switch (ul_reason_for_call) | ||||
|    { | ||||
|       case DLL_PROCESS_ATTACH: | ||||
|       { | ||||
|          g_hModule = hModule; | ||||
|  | ||||
|          // Setup the path to the client and auth mechanisms config folders | ||||
|          if (SHGetFolderPath(NULL, | ||||
|                              CSIDL_PROGRAM_FILES, | ||||
|                              NULL, | ||||
|                              0, | ||||
|                              programFilesFolder) == 0) | ||||
|          { | ||||
|             strcpy(clientConfigFolder, programFilesFolder); | ||||
|             PathAppend(clientConfigFolder, clientConfigFolderPartialPath); | ||||
|  | ||||
|             strcpy(mechConfigFolder, programFilesFolder); | ||||
|             PathAppend(mechConfigFolder, mechConfigFolderPartialPath); | ||||
|  | ||||
|             // Allocate module mutex | ||||
|             g_hModuleMutex = CreateMutex(NULL, FALSE, NULL); | ||||
|             if (! g_hModuleMutex) | ||||
|             { | ||||
|                // Module initialization failed | ||||
|                OutputDebugString("CASAAUTH -DllMain- Failed to create mutex\n"); | ||||
|                retStatus = FALSE; | ||||
|             } | ||||
|          } | ||||
|          else | ||||
|          { | ||||
|             // Failed to obtain the Program Files path | ||||
|             OutputDebugString("CASAAUTH -DllMain- Failed to obtain the Program Files path\n"); | ||||
|             retStatus = FALSE; | ||||
|          } | ||||
|  | ||||
|          break; | ||||
|       } | ||||
|  | ||||
|       case DLL_THREAD_ATTACH: | ||||
|       { | ||||
|          g_hModule = hModule; | ||||
|          break; | ||||
|       } | ||||
|  | ||||
|       case DLL_THREAD_DETACH: | ||||
|          break; | ||||
|  | ||||
|       case DLL_PROCESS_DETACH: | ||||
|       { | ||||
|          /* Don't uninitialize on windows | ||||
|          tbd | ||||
|          */ | ||||
|          break; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     return retStatus; | ||||
| } | ||||
|  | ||||
| //++======================================================================= | ||||
| // | ||||
| // DllCanUnloadNow | ||||
| // | ||||
| // Synopsis | ||||
| // | ||||
| // | ||||
| STDAPI | ||||
| DllCanUnloadNow() | ||||
| // | ||||
| // Input Arguments | ||||
| // | ||||
| // Ouput Arguments | ||||
| // | ||||
| // Return Value | ||||
| //    S_OK    The DLL can be unloaded. | ||||
| //    S_FALSE The DLL cannot be unloaded now. | ||||
| // | ||||
| // Description | ||||
| //    An Exported Function. | ||||
| //    DLLs that support the OLE Component Object Model (COM) should implement | ||||
| //    and export DllCanUnloadNow. | ||||
| //    A call to DllCanUnloadNow determines whether the DLL from which it is | ||||
| //    exported is still in use. A DLL is no longer in use when it is not | ||||
| //    managing  any existing objects (the reference count on all of its objects | ||||
| //    is 0). | ||||
| //    DllCanUnloadNow returns S_FALSE if there are any existing references to | ||||
| //    objects that the DLL manages. | ||||
| // | ||||
| // Environment | ||||
| // | ||||
| // See Also | ||||
| // | ||||
| //=======================================================================-- | ||||
| { | ||||
|    // tbd | ||||
|    return ((g_ulCount == 0 && g_ulLock == 0) ? S_OK : S_FALSE); | ||||
| } | ||||
|  | ||||
| //========================================================================= | ||||
| //========================================================================= | ||||
|  | ||||
							
								
								
									
										580
									
								
								CASA-auth-token/client/lib/windows/platform.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										580
									
								
								CASA-auth-token/client/lib/windows/platform.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,580 @@ | ||||
| /*********************************************************************** | ||||
|  *  | ||||
|  *  Copyright (C) 2006 Novell, Inc. All Rights Reserved. | ||||
|  * | ||||
|  *  This library is free software; you can redistribute it and/or | ||||
|  *  modify it under the terms of the GNU Lesser General Public | ||||
|  *  License as published by the Free Software Foundation; version 2.1 | ||||
|  *  of the License. | ||||
|  * | ||||
|  *  This library is distributed in the hope that it will be useful, | ||||
|  *  but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  *  Library Lesser General Public License for more details. | ||||
|  * | ||||
|  *  You should have received a copy of the GNU Lesser General Public | ||||
|  *  License along with this library; if not, Novell, Inc. | ||||
|  *  | ||||
|  *  To contact Novell about this file by physical or electronic mail,  | ||||
|  *  you may find current contact information at www.novell.com. | ||||
|  *  | ||||
|  *  Author: Juan Carlos Luciani <jluciani@novell.com> | ||||
|  * | ||||
|  ***********************************************************************/ | ||||
|  | ||||
| //===[ Include files ]===================================================== | ||||
|  | ||||
| #include "internal.h" | ||||
|  | ||||
| //===[ Type definitions ]================================================== | ||||
|  | ||||
| // | ||||
| // Normalized Host Name Cache Entry definition | ||||
| // | ||||
| typedef struct _NormalizedHostNameCacheEntry | ||||
| { | ||||
|    LIST_ENTRY  listEntry; | ||||
|    char        *pHostName; | ||||
|    char        *pNormalizedHostName; | ||||
|    int         buffLengthRequired; | ||||
|      | ||||
| } NormalizedHostNameCacheEntry, *PNormalizedHostNameCacheEntry; | ||||
|  | ||||
|  | ||||
| //===[ Function prototypes ]=============================================== | ||||
|  | ||||
| //===[ Global variables ]================================================== | ||||
|  | ||||
| // Normalized host name cache list head | ||||
| static | ||||
| LIST_ENTRY  normalizedHostNameCacheListHead; | ||||
|  | ||||
| // Synchronization mutex for the normalized host name cache | ||||
| static | ||||
| HANDLE   hNormalizedHostNameCacheMutex; | ||||
|  | ||||
| // Client configuration file folder | ||||
| char  clientConfigFolder[MAX_PATH]; | ||||
| char  clientConfigFolderPartialPath[] = "Novell\\Casa\\Etc\\Auth"; | ||||
|  | ||||
| // Authentication mechanism configuration file folder | ||||
| char  mechConfigFolder[MAX_PATH]; | ||||
| char  mechConfigFolderPartialPath[] = "Novell\\Casa\\Etc\\Auth\\Mechanisms"; | ||||
|  | ||||
| // Path separator | ||||
| char  pathCharString[] = "\\"; | ||||
|  | ||||
| //++======================================================================= | ||||
| CasaStatus | ||||
| CreateUserMutex( | ||||
|    HANDLE *phMutex | ||||
|    ) | ||||
| // | ||||
| //  Arguments:  | ||||
| // | ||||
| //  Returns:    | ||||
| // | ||||
| //  Abstract:   | ||||
| // | ||||
| //  Notes: | ||||
| // | ||||
| // L2 | ||||
| //=======================================================================-- | ||||
| { | ||||
|    CasaStatus  retStatus = CASA_STATUS_SUCCESS; | ||||
|    char        *pUsername = NULL; | ||||
|    DWORD       nameLength = 0; | ||||
|  | ||||
|    DbgTrace(1, "-CreateUserMutex- Start\n", 0); | ||||
|  | ||||
|    // Get the size of the buffer required to obtain the user name | ||||
|    GetUserName(pUsername, &nameLength); | ||||
|    if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) | ||||
|    { | ||||
|       // Allocate buffer to hold the user name | ||||
|       pUsername = (char*) malloc(nameLength); | ||||
|       if (pUsername) | ||||
|       { | ||||
|          // Get the name of the user | ||||
|          if (GetUserName(pUsername, &nameLength)) | ||||
|          { | ||||
|             SECURITY_ATTRIBUTES  mutexAttributes; | ||||
|             char                 mutexName[256]; | ||||
|  | ||||
|             // Now lets create a global semaphore for the | ||||
|             // user and allow its handle to be inherited. | ||||
|             mutexAttributes.nLength = sizeof(mutexAttributes); | ||||
|             mutexAttributes.lpSecurityDescriptor = NULL; | ||||
|             mutexAttributes.bInheritHandle = TRUE; | ||||
|             if (sprintf(mutexName, "Global\\CASA_Auth_Mutex_%s", pUsername) != -1) | ||||
|             { | ||||
|                *phMutex = CreateMutex(&mutexAttributes, | ||||
|                                       FALSE, | ||||
|                                       mutexName); | ||||
|                if (*phMutex == NULL) | ||||
|                { | ||||
|                   DbgTrace(0, "-CreateUserMutex- CreateMutex failed, error = %d\n", GetLastError()); | ||||
|                   retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, | ||||
|                                               CASA_FACILITY_AUTHTOKEN, | ||||
|                                               CASA_STATUS_UNSUCCESSFUL); | ||||
|                } | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                DbgTrace(0, "-CreateUserMutex- sprintf failed, error = %d\n", GetLastError()); | ||||
|                retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, | ||||
|                                            CASA_FACILITY_AUTHTOKEN, | ||||
|                                            CASA_STATUS_UNSUCCESSFUL); | ||||
|             } | ||||
|          } | ||||
|          else | ||||
|          { | ||||
|             DbgTrace(0, "-CreateUserMutex- GetUserName failed, error = %d\n", GetLastError()); | ||||
|             retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, | ||||
|                                         CASA_FACILITY_AUTHTOKEN, | ||||
|                                         CASA_STATUS_UNSUCCESSFUL); | ||||
|          } | ||||
|  | ||||
|          // Free the buffer allocated to hold the user name | ||||
|          free(pUsername); | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|          DbgTrace(0, "-CreateUserMutex- Buffer allocation error\n", 0); | ||||
|          retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, | ||||
|                                      CASA_FACILITY_AUTHTOKEN, | ||||
|                                      CASA_STATUS_INSUFFICIENT_RESOURCES); | ||||
|       } | ||||
|    } | ||||
|    else | ||||
|    { | ||||
|       DbgTrace(0, "-CreateUserMutex- Unexpected GetUserName error, error = %d\n", GetLastError()); | ||||
|       retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, | ||||
|                                   CASA_FACILITY_AUTHTOKEN, | ||||
|                                   CASA_STATUS_UNSUCCESSFUL); | ||||
|    } | ||||
|  | ||||
|    DbgTrace(1, "-CreateUserMutex- End, retStatus\n", retStatus); | ||||
|  | ||||
|    return retStatus; | ||||
| } | ||||
|  | ||||
|  | ||||
| //++======================================================================= | ||||
| void | ||||
| AcquireUserMutex( | ||||
|    HANDLE hMutex | ||||
|    ) | ||||
| // | ||||
| //  Arguments:  | ||||
| // | ||||
| //  Returns:    | ||||
| // | ||||
| //  Abstract:   | ||||
| // | ||||
| //  Notes: | ||||
| // | ||||
| // L2 | ||||
| //=======================================================================-- | ||||
| { | ||||
|    DbgTrace(2, "-AcquireUserMutex- Start\n", 0); | ||||
|  | ||||
|    WaitForSingleObject(hMutex, INFINITE); | ||||
|  | ||||
|    DbgTrace(2, "-AcquireUserMutex- End\n", 0); | ||||
| } | ||||
|  | ||||
|  | ||||
| //++======================================================================= | ||||
| void | ||||
| ReleaseUserMutex( | ||||
|    HANDLE hMutex | ||||
|    ) | ||||
| // | ||||
| //  Arguments:  | ||||
| // | ||||
| //  Returns:    | ||||
| // | ||||
| //  Abstract:   | ||||
| // | ||||
| //  Notes: | ||||
| // | ||||
| // L2 | ||||
| //=======================================================================-- | ||||
| { | ||||
|    DbgTrace(2, "-ReleaseUserMutex- Start\n", 0); | ||||
|  | ||||
|    if (ReleaseMutex(hMutex) == 0) | ||||
|    { | ||||
|       DbgTrace(0, "-ReleaseUserMutex- ReleaseMutex failed, error = %d\n", GetLastError()); | ||||
|    } | ||||
|  | ||||
|    DbgTrace(2, "-ReleaseUserMutex- End\n", 0); | ||||
| } | ||||
|  | ||||
|  | ||||
| //++======================================================================= | ||||
| void | ||||
| DestroyUserMutex( | ||||
|    HANDLE hMutex | ||||
|    ) | ||||
| // | ||||
| //  Arguments:  | ||||
| // | ||||
| //  Returns:    | ||||
| // | ||||
| //  Abstract:   | ||||
| // | ||||
| //  Notes: | ||||
| // | ||||
| // L2 | ||||
| //=======================================================================-- | ||||
| { | ||||
|    DbgTrace(2, "-DestroyUserMutex- Start\n", 0); | ||||
|  | ||||
|    if (CloseHandle(hMutex) == 0) | ||||
|    { | ||||
|       DbgTrace(0, "-DestroyUserMutex- CloseHandle failed, error = %d\n", GetLastError()); | ||||
|    } | ||||
|  | ||||
|    DbgTrace(2, "-DestroyUserMutex- End\n", 0); | ||||
| } | ||||
|  | ||||
|  | ||||
| //++======================================================================= | ||||
| LIB_HANDLE | ||||
| OpenLibrary( | ||||
|    IN    char *pFileName) | ||||
| // | ||||
| //  Arguments:  | ||||
| // | ||||
| //  Returns:    | ||||
| // | ||||
| //  Abstract:   | ||||
| // | ||||
| //  Notes: | ||||
| // | ||||
| // L2 | ||||
| //=======================================================================-- | ||||
| { | ||||
|    LIB_HANDLE  libHandle; | ||||
|  | ||||
|    DbgTrace(1, "-OpenLibrary- Start\n", 0); | ||||
|  | ||||
|    libHandle = LoadLibrary(pFileName); | ||||
|    if (libHandle == NULL) | ||||
|    { | ||||
|       DbgTrace(0, "-OpenLibrary- Not able to load library, error = %d\n", GetLastError()); | ||||
|    } | ||||
|  | ||||
|    DbgTrace(1, "-OpenLibrary- End, handle = %08X\n", libHandle); | ||||
|  | ||||
|    return libHandle; | ||||
| } | ||||
|  | ||||
|  | ||||
| //++======================================================================= | ||||
| void | ||||
| CloseLibrary( | ||||
|    IN    LIB_HANDLE libHandle) | ||||
| // | ||||
| //  Arguments:  | ||||
| // | ||||
| //  Returns:    | ||||
| // | ||||
| //  Abstract:   | ||||
| // | ||||
| //  Notes: | ||||
| // | ||||
| // L2 | ||||
| //=======================================================================-- | ||||
| { | ||||
|    DbgTrace(1, "-CloseLibrary- Start\n", 0); | ||||
|  | ||||
|    FreeLibrary(libHandle); | ||||
|  | ||||
|    DbgTrace(1, "-CloseLibrary- End\n", 0); | ||||
| } | ||||
|  | ||||
|  | ||||
| //++======================================================================= | ||||
| void* | ||||
| GetFunctionPtr( | ||||
|    IN    LIB_HANDLE libHandle, | ||||
|    IN    char *pFunctionName) | ||||
| // | ||||
| //  Arguments:  | ||||
| // | ||||
| //  Returns:    | ||||
| // | ||||
| //  Abstract:   | ||||
| // | ||||
| //  Notes: | ||||
| // | ||||
| // L2 | ||||
| //=======================================================================-- | ||||
| { | ||||
|    void  *pFuncPtr; | ||||
|  | ||||
|    DbgTrace(1, "-GetFunctionPtr- Start\n", 0); | ||||
|  | ||||
|    pFuncPtr = GetProcAddress(libHandle, pFunctionName); | ||||
|    if (pFuncPtr == NULL) | ||||
|    { | ||||
|       DbgTrace(0, "-GetFunctionPtr- Not able to obtain func ptr, error = %d\n", GetLastError()); | ||||
|    } | ||||
|  | ||||
|    DbgTrace(1, "-GetFunctionPtr- End, pFuncPtr = %08X\n", pFuncPtr); | ||||
|  | ||||
|    return pFuncPtr; | ||||
| } | ||||
|  | ||||
|  | ||||
| //++======================================================================= | ||||
| char* | ||||
| NormalizeHostName( | ||||
|    IN    const char *pHostName) | ||||
| // | ||||
| //  Arguments:  | ||||
| // | ||||
| //  Returns:    | ||||
| // | ||||
| //  Abstract:   | ||||
| // | ||||
| //  Notes: | ||||
| // | ||||
| // L2 | ||||
| //=======================================================================-- | ||||
| { | ||||
|    char                          *pNormalizedName = NULL; | ||||
|    LIST_ENTRY                    *pListEntry; | ||||
|    NormalizedHostNameCacheEntry  *pEntry = NULL; | ||||
|  | ||||
|    DbgTrace(1, "-NormalizeHostName- Start\n", 0); | ||||
|  | ||||
|    // Obtain our synchronization mutex | ||||
|    WaitForSingleObject(hNormalizedHostNameCacheMutex, INFINITE); | ||||
|  | ||||
|    // First try to find an entry in the normalized host name cache | ||||
|    // for the host name provided. | ||||
|    pListEntry = normalizedHostNameCacheListHead.Flink; | ||||
|    while (pListEntry != &normalizedHostNameCacheListHead) | ||||
|    { | ||||
|       // Get pointer to the entry | ||||
|       pEntry = CONTAINING_RECORD(pListEntry, NormalizedHostNameCacheEntry, listEntry); | ||||
|  | ||||
|       // Check if the entry is for the host name | ||||
|       if (strcmp(pHostName, pEntry->pHostName) == 0) | ||||
|       { | ||||
|          // This entry corresponds to the given host name | ||||
|          break; | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|          // The entry does not correspond to the given host name | ||||
|          pEntry = NULL; | ||||
|       } | ||||
|  | ||||
|       // Advance to the next entry | ||||
|       pListEntry = pListEntry->Flink; | ||||
|    } | ||||
|  | ||||
|    // Check if we found an entry in our cache for the given host name | ||||
|    if (pEntry) | ||||
|    { | ||||
|       // Entry found, obtain the normalized name from it. | ||||
|       pNormalizedName = (char*) malloc(pEntry->buffLengthRequired); | ||||
|       if (pNormalizedName) | ||||
|       { | ||||
|          // Copy the normalized name onto the allocated buffer | ||||
|          strcpy(pNormalizedName, pEntry->pNormalizedHostName); | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|          DbgTrace(0, "-NormalizeHostName- Buffer allocation error\n", 0); | ||||
|       } | ||||
|    } | ||||
|    else | ||||
|    { | ||||
|       // An entry was not found in our cache, create one. | ||||
|       pEntry = (NormalizedHostNameCacheEntry*) malloc(sizeof(NormalizedHostNameCacheEntry)); | ||||
|       if (pEntry) | ||||
|       { | ||||
|          // Zero the entry | ||||
|          memset(pEntry, 0, sizeof(*pEntry)); | ||||
|  | ||||
|          // Allocate a buffer to hold the host name in the entry | ||||
|          pEntry->pHostName = (char*) malloc(strlen(pHostName) + 1); | ||||
|          if (pEntry->pHostName) | ||||
|          { | ||||
|             struct hostent       *pLookupResult; | ||||
|             struct sockaddr_in   sockAddr = {0}; | ||||
|  | ||||
|             // Copy the host name given into the allocated buffer | ||||
|             strcpy(pEntry->pHostName, pHostName); | ||||
|  | ||||
|             // Now try to resolve the normalized name | ||||
|             pLookupResult = gethostbyname(pHostName); | ||||
|             if (pLookupResult && pLookupResult->h_addrtype == AF_INET) | ||||
|             { | ||||
|                char  dnsHostName[NI_MAXHOST]; | ||||
|  | ||||
|                // Set up a sockaddr structure | ||||
|                sockAddr.sin_family = AF_INET; | ||||
|                sockAddr.sin_addr.S_un.S_addr = *((int*) pLookupResult->h_addr_list[0]); | ||||
|  | ||||
|                // Now try to resolve the name using DNS | ||||
|                if (getnameinfo((const struct sockaddr*) &sockAddr, | ||||
|                                sizeof(sockAddr), | ||||
|                                dnsHostName, | ||||
|                                sizeof(dnsHostName), | ||||
|                                NULL, | ||||
|                                0, | ||||
|                                NI_NAMEREQD) == 0) | ||||
|                { | ||||
|                   // We resolved the address to a DNS name, use it as the normalized name. | ||||
|                   pEntry->buffLengthRequired = (int) strlen(dnsHostName) + 1; | ||||
|                   pEntry->pNormalizedHostName = (char*) malloc(pEntry->buffLengthRequired); | ||||
|                   if (pEntry->pNormalizedHostName) | ||||
|                   { | ||||
|                      // Copy the dns name | ||||
|                      strcpy(pEntry->pNormalizedHostName, dnsHostName); | ||||
|                   } | ||||
|                   else | ||||
|                   { | ||||
|                      DbgTrace(0, "-NormalizeHostName- Buffer allocation error\n", 0); | ||||
|                   } | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   DbgTrace(0, "-NormalizeHostName- getnameInfo failed, error %d\n", WSAGetLastError()); | ||||
|  | ||||
|                   // Not able to resolve the name in DNS, just use the host name as | ||||
|                   // the normalized name. | ||||
|                   pEntry->buffLengthRequired = (int) strlen(pHostName) + 1; | ||||
|                   pEntry->pNormalizedHostName = (char*) malloc(pEntry->buffLengthRequired); | ||||
|                   if (pEntry->pNormalizedHostName) | ||||
|                   { | ||||
|                      // Copy the host name | ||||
|                      strcpy(pEntry->pNormalizedHostName, pHostName); | ||||
|                   } | ||||
|                   else | ||||
|                   { | ||||
|                      DbgTrace(0, "-NormalizeHostName- Buffer allocation error\n", 0); | ||||
|                   } | ||||
|                } | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                DbgTrace(0, "-NormalizeHostName- Name resolution failed, error = %d\n", WSAGetLastError()); | ||||
|             } | ||||
|          } | ||||
|          else | ||||
|          { | ||||
|             DbgTrace(0, "-NormalizeHostName- Buffer allocation error\n", 0); | ||||
|  | ||||
|             // Free the space allocated for the entry | ||||
|             free(pEntry); | ||||
|          } | ||||
|  | ||||
|          // Proceed based on whether or not we normalized the name | ||||
|          if (pEntry->pNormalizedHostName) | ||||
|          { | ||||
|             // The name was normalized, save the entry in our cache. | ||||
|             InsertHeadList(&normalizedHostNameCacheListHead, &pEntry->listEntry); | ||||
|  | ||||
|             // Return the normalized name present in the entry | ||||
|             pNormalizedName = (char*) malloc(pEntry->buffLengthRequired); | ||||
|             if (pNormalizedName) | ||||
|             { | ||||
|                // Copy the normalized name onto the allocated buffer | ||||
|                strcpy(pNormalizedName, pEntry->pNormalizedHostName); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                DbgTrace(0, "-NormalizeHostName- Buffer allocation error\n", 0); | ||||
|             } | ||||
|          } | ||||
|          else | ||||
|          { | ||||
|             // The host name was not normalized, free allocated resources. | ||||
|             if (pEntry->pHostName) | ||||
|                free(pEntry->pHostName); | ||||
|             free(pEntry); | ||||
|          } | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|          DbgTrace(0, "-NormalizeHostName- Buffer allocation error\n", 0); | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    // Release our synchronization mutex | ||||
|    if (ReleaseMutex(hNormalizedHostNameCacheMutex) == 0) | ||||
|    { | ||||
|       DbgTrace(0, "-NormalizeHostName- ReleaseMutex failed, error\n", 0); | ||||
|    } | ||||
|  | ||||
|    DbgTrace(1, "-NormalizeHostName- End, pNormalizedName = %08X\n", pNormalizedName); | ||||
|  | ||||
|    return pNormalizedName; | ||||
| } | ||||
|  | ||||
|  | ||||
| //++======================================================================= | ||||
| CasaStatus | ||||
| InitializeHostNameNormalization(void) | ||||
| // | ||||
| //  Arguments:  | ||||
| // | ||||
| //  Returns:    | ||||
| // | ||||
| //  Abstract:   | ||||
| // | ||||
| //  Notes: | ||||
| // | ||||
| // L2 | ||||
| //=======================================================================-- | ||||
| { | ||||
|    CasaStatus  retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, | ||||
|                                            CASA_FACILITY_AUTHTOKEN, | ||||
|                                            CASA_STATUS_UNSUCCESSFUL); | ||||
|    int         winsockStartupResult; | ||||
|    WSADATA     winsockData; | ||||
|  | ||||
|    DbgTrace(1, "-InitializeHostNameNormalization- Start\n", 0); | ||||
|  | ||||
|    // Initialize winsock | ||||
|    if ((winsockStartupResult = WSAStartup(MAKEWORD(2,2), &winsockData)) == 0) | ||||
|    { | ||||
|       // Initialize the cache list head | ||||
|       InitializeListHead(&normalizedHostNameCacheListHead); | ||||
|  | ||||
|       // Create a cache mutex only applicable to the current process | ||||
|       hNormalizedHostNameCacheMutex = CreateMutex(NULL, | ||||
|                                                   FALSE, | ||||
|                                                   NULL); | ||||
|       if (hNormalizedHostNameCacheMutex != NULL) | ||||
|       { | ||||
|          retStatus = CASA_STATUS_SUCCESS; | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|          DbgTrace(0, "-InitializeHostNameNormalization- CreateMutex failed, error = %d\n", GetLastError()); | ||||
|       } | ||||
|    } | ||||
|    else | ||||
|    { | ||||
|       DbgTrace(0, "-InitializeHostNameNormalization- WSAStartup failed, error = %d\n", winsockStartupResult); | ||||
|    } | ||||
|  | ||||
|    DbgTrace(1, "-InitializeHostNameNormalization- End, retStatus = %08X\n", retStatus); | ||||
|  | ||||
|    return retStatus; | ||||
| } | ||||
|  | ||||
|  | ||||
| //++======================================================================= | ||||
| //++======================================================================= | ||||
| //++======================================================================= | ||||
|  | ||||
							
								
								
									
										103
									
								
								CASA-auth-token/client/lib/windows/platform.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								CASA-auth-token/client/lib/windows/platform.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,103 @@ | ||||
| /*********************************************************************** | ||||
|  *  | ||||
|  *  Copyright (C) 2006 Novell, Inc. All Rights Reserved. | ||||
|  * | ||||
|  *  This library is free software; you can redistribute it and/or | ||||
|  *  modify it under the terms of the GNU Lesser General Public | ||||
|  *  License as published by the Free Software Foundation; version 2.1 | ||||
|  *  of the License. | ||||
|  * | ||||
|  *  This library is distributed in the hope that it will be useful, | ||||
|  *  but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  *  Library Lesser General Public License for more details. | ||||
|  * | ||||
|  *  You should have received a copy of the GNU Lesser General Public | ||||
|  *  License along with this library; if not, Novell, Inc. | ||||
|  *  | ||||
|  *  To contact Novell about this file by physical or electronic mail,  | ||||
|  *  you may find current contact information at www.novell.com. | ||||
|  *  | ||||
|  *  Author: Juan Carlos Luciani <jluciani@novell.com> | ||||
|  * | ||||
|  ***********************************************************************/ | ||||
|  | ||||
|  | ||||
| //===[ Include files ]===================================================== | ||||
|  | ||||
| #include <winsock2.h> | ||||
| #include <windows.h> | ||||
| #include <stdio.h> | ||||
| #include <aclapi.h> | ||||
| #include <winerror.h> | ||||
| #include <ws2tcpip.h> | ||||
| #include <winhttp.h> | ||||
|  | ||||
| //===[ Type definitions ]================================================== | ||||
|  | ||||
| #ifndef CONTAINING_RECORD | ||||
| #define CONTAINING_RECORD(address, type, field) ((type *)(     \ | ||||
|              (char*)(address) -                                \ | ||||
|              (char*)(&((type *)0)->field))) | ||||
| #endif | ||||
|  | ||||
| // | ||||
| // DbgTrace macro define | ||||
| // | ||||
| //#define DbgTrace(LEVEL, X, Y) {                          \ | ||||
| //char printBuff[256];                                     \ | ||||
| //   if (LEVEL == 0 || DebugLevel >= LEVEL)                \ | ||||
| //   {                                                     \ | ||||
| //      _snprintf(printBuff, sizeof(printBuff), X, Y);     \ | ||||
| //      printf("CASA_AuthToken %s", printBuff);                 \ | ||||
| //   }                                                     \ | ||||
| //} | ||||
| #define DbgTrace(LEVEL, X, Y) {                                \ | ||||
| char formatBuff[128];                                          \ | ||||
| char printBuff[256];                                           \ | ||||
|    if (LEVEL == 0 || DebugLevel >= LEVEL)                      \ | ||||
|    {                                                           \ | ||||
|       strcpy(formatBuff, "CASA_AuthToken ");                        \ | ||||
|       strncat(formatBuff, X, sizeof(formatBuff) - 10);         \ | ||||
|       _snprintf(printBuff, sizeof(printBuff), formatBuff, Y);  \ | ||||
|       OutputDebugString(printBuff);                            \ | ||||
|    }                                                           \ | ||||
| } | ||||
|  | ||||
| // | ||||
| // Rpc Session definition | ||||
| // | ||||
| typedef struct _RpcSession | ||||
| { | ||||
|    HINTERNET   hSession; | ||||
|    HINTERNET   hConnection; | ||||
|    char        *pHostName; | ||||
|  | ||||
| } RpcSession, *PRpcSession; | ||||
|  | ||||
|  | ||||
| // | ||||
| // Other definitions | ||||
| // | ||||
| #define LIB_HANDLE HMODULE | ||||
| #define bool BOOLEAN | ||||
| #define true TRUE | ||||
| #define false FALSE | ||||
|  | ||||
| #define AcquireModuleMutex    WaitForSingleObjectEx(g_hModuleMutex, INFINITE, FALSE) | ||||
| #define ReleaseModuleMutex    ReleaseMutex(g_hModuleMutex) | ||||
|  | ||||
| //===[ Inlines functions   ]=============================================== | ||||
|  | ||||
| //===[ Function prototypes ]=============================================== | ||||
|  | ||||
| //===[ Global externals ]================================================== | ||||
|  | ||||
| //===[ External prototypes ]=============================================== | ||||
|  | ||||
| //===[ External data ]===================================================== | ||||
|  | ||||
| extern HANDLE g_hModuleMutex; | ||||
|  | ||||
| //========================================================================= | ||||
|  | ||||
							
								
								
									
										799
									
								
								CASA-auth-token/client/lib/windows/rpc.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										799
									
								
								CASA-auth-token/client/lib/windows/rpc.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,799 @@ | ||||
| /*********************************************************************** | ||||
|  *  | ||||
|  *  Copyright (C) 2006 Novell, Inc. All Rights Reserved. | ||||
|  * | ||||
|  *  This library is free software; you can redistribute it and/or | ||||
|  *  modify it under the terms of the GNU Lesser General Public | ||||
|  *  License as published by the Free Software Foundation; version 2.1 | ||||
|  *  of the License. | ||||
|  * | ||||
|  *  This library is distributed in the hope that it will be useful, | ||||
|  *  but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  *  Library Lesser General Public License for more details. | ||||
|  * | ||||
|  *  You should have received a copy of the GNU Lesser General Public | ||||
|  *  License along with this library; if not, Novell, Inc. | ||||
|  *  | ||||
|  *  To contact Novell about this file by physical or electronic mail,  | ||||
|  *  you may find current contact information at www.novell.com. | ||||
|  *  | ||||
|  *  Author: Juan Carlos Luciani <jluciani@novell.com> | ||||
|  * | ||||
|  ***********************************************************************/ | ||||
|  | ||||
|  | ||||
| //===[ Include files ]===================================================== | ||||
|  | ||||
| #include "internal.h" | ||||
|  | ||||
| //===[ Type definitions ]================================================== | ||||
|  | ||||
| #define INITIAL_RESPONSE_DATA_BUF_SIZE 1028 | ||||
| #define INCREMENT_RESPONSE_DATA_BUF_SIZE 256 | ||||
|  | ||||
| #define MAX_RPC_RETRIES 3 | ||||
|  | ||||
| //===[ Function prototypes ]=============================================== | ||||
|  | ||||
| //===[ Global variables ]================================================== | ||||
|  | ||||
| //++======================================================================= | ||||
| static | ||||
| CasaStatus | ||||
| CopyMultiToWideAlloc( | ||||
|    IN    char *pMulti, | ||||
|    IN    int multiSize, | ||||
|    INOUT LPWSTR *ppWide, | ||||
|    INOUT int *pWideSize) | ||||
| // | ||||
| //  Arguments:  | ||||
| // | ||||
| //  Returns:    | ||||
| // | ||||
| //  Abstract:   | ||||
| // | ||||
| //  Notes: | ||||
| // | ||||
| // L2 | ||||
| //=======================================================================-- | ||||
| { | ||||
|    int      retStatus; | ||||
|    int      size, i; | ||||
|  | ||||
|    DbgTrace(2, "-CopyMultiToWideAlloc- Start\n", 0); | ||||
|  | ||||
|    size = (multiSize + 1) * sizeof(WCHAR); | ||||
|  | ||||
|    if ((*ppWide = (PWCHAR) malloc(size)) != NULL) | ||||
|    { | ||||
|       for (i = 0; i < multiSize; i++) | ||||
|       { | ||||
|          *(*ppWide + i) = (unsigned char) *(pMulti + i); | ||||
|       } | ||||
|  | ||||
|       *(*ppWide + i) = L'\0'; | ||||
|  | ||||
|       if (pWideSize) | ||||
|       { | ||||
|          *pWideSize = size - sizeof(WCHAR); | ||||
|       } | ||||
|  | ||||
|       retStatus = CASA_STATUS_SUCCESS; | ||||
|    } | ||||
|    else | ||||
|    { | ||||
|       retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, | ||||
|                                   CASA_FACILITY_AUTHTOKEN, | ||||
|                                   CASA_STATUS_INSUFFICIENT_RESOURCES); | ||||
|    } | ||||
|  | ||||
|    DbgTrace(2, "-CopyMultiToWideAlloc- End, retStatus = %08X\n", retStatus); | ||||
|  | ||||
|    return retStatus; | ||||
| } | ||||
|  | ||||
|  | ||||
| //++======================================================================= | ||||
| static | ||||
| CasaStatus | ||||
| CopyWideToMultiAlloc( | ||||
|    IN    LPWSTR pWide, | ||||
|    IN    int wideSize, | ||||
|    INOUT char **ppMulti, | ||||
|    INOUT int *pMultiSize) | ||||
| // | ||||
| //  Arguments:  | ||||
| // | ||||
| //  Returns:    | ||||
| // | ||||
| //  Abstract:   | ||||
| // | ||||
| //  Notes: | ||||
| // | ||||
| // L2 | ||||
| //=======================================================================-- | ||||
| { | ||||
|    int      retStatus; | ||||
|    int      size, i; | ||||
|  | ||||
|    DbgTrace(2, "-CopyWideToMultiAlloc- Start\n", 0); | ||||
|  | ||||
|    size = wideSize + 1; | ||||
|  | ||||
|    if ((*ppMulti = malloc(size)) != NULL) | ||||
|    { | ||||
|       for (i = 0; i < wideSize; i++) | ||||
|       { | ||||
|          *(*ppMulti + i) = (char) *(pWide + i); | ||||
|       } | ||||
|  | ||||
|       *(*ppMulti + i) = '\0'; | ||||
|  | ||||
|       if (pMultiSize) | ||||
|       { | ||||
|          *pMultiSize = size - 1; | ||||
|       } | ||||
|  | ||||
|       retStatus = CASA_STATUS_SUCCESS; | ||||
|    } | ||||
|    else | ||||
|    { | ||||
|       retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, | ||||
|                                   CASA_FACILITY_AUTHTOKEN, | ||||
|                                   CASA_STATUS_INSUFFICIENT_RESOURCES); | ||||
|    } | ||||
|  | ||||
|    DbgTrace(2, "-CopyWideToMultiAlloc- End, retStatus = %08X\n", retStatus); | ||||
|  | ||||
|    return retStatus; | ||||
| } | ||||
|  | ||||
|  | ||||
| //++======================================================================= | ||||
| RpcSession* | ||||
| OpenRpcSession( | ||||
|    IN    char *pHostName, | ||||
|    IN    uint16_t hostPort) | ||||
| // | ||||
| //  Arguments:  | ||||
| // | ||||
| //  Returns:    | ||||
| // | ||||
| //  Abstract:   | ||||
| // | ||||
| //  Notes: | ||||
| // | ||||
| // L2 | ||||
| //=======================================================================-- | ||||
| { | ||||
|    RpcSession  *pSession; | ||||
|    bool        success = false; | ||||
|  | ||||
|    DbgTrace(1, "-OpenRpcSession- Start\n", 0); | ||||
|  | ||||
|    // Allocate space for the session | ||||
|    pSession = (RpcSession*) malloc(sizeof(*pSession)); | ||||
|    if (pSession) | ||||
|    { | ||||
|       // Zero the session structure | ||||
|       memset(pSession, 0, sizeof(*pSession)); | ||||
|  | ||||
|       // Save copy of the hostname | ||||
|       pSession->pHostName = malloc(strlen(pHostName) + 1); | ||||
|       if (pSession->pHostName) | ||||
|       { | ||||
|          strcpy(pSession->pHostName, pHostName); | ||||
|  | ||||
|          // Open a Winhttp session | ||||
|          pSession->hSession = WinHttpOpen(L"CASA Client/1.0", | ||||
|                                           WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, | ||||
|                                           WINHTTP_NO_PROXY_NAME, | ||||
|                                           WINHTTP_NO_PROXY_BYPASS, | ||||
|                                           0); | ||||
|          if (pSession->hSession) | ||||
|          { | ||||
|             LPWSTR   pWideHostName; | ||||
|             int      wideHostLen; | ||||
|  | ||||
|             // Session opened, now convert the host name to Unicode so that | ||||
|             // we can open a connection. | ||||
|             if (CopyMultiToWideAlloc(pHostName, | ||||
|                                      (int) strlen(pHostName), | ||||
|                                      &pWideHostName, | ||||
|                                      &wideHostLen) == CASA_STATUS_SUCCESS) | ||||
|             { | ||||
|                // Now open connection | ||||
|                pSession->hConnection = WinHttpConnect(pSession->hSession, | ||||
|                                                       pWideHostName, | ||||
|                                                       hostPort, | ||||
|                                                       0); | ||||
|                if (pSession->hConnection == NULL) | ||||
|                { | ||||
|                   DbgTrace(0, "-OpenRpcSession- Failed to open connection, error = %d\n", GetLastError()); | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   success = true; | ||||
|                } | ||||
|  | ||||
|                // Free the host name wide string buffer | ||||
|                free(pWideHostName); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                DbgTrace(0, "-OpenRpcSession- Error converting host name to wide string\n", 0); | ||||
|             } | ||||
|          } | ||||
|          else | ||||
|          { | ||||
|             DbgTrace(0, "-OpenRpcSession- Failed to open session, error = %d\n", GetLastError()); | ||||
|          } | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|          DbgTrace(0, "-OpenRpcSession- Failed to allocate buffer for host name\n", 0); | ||||
|       } | ||||
|    } | ||||
|    else | ||||
|    { | ||||
|       DbgTrace(0, "-OpenRpcSession- Failed to allocate buffer for rpc session\n", 0); | ||||
|    } | ||||
|  | ||||
|    // Clean up if we did not succeed | ||||
|    if (!success) | ||||
|    { | ||||
|       if (pSession) | ||||
|       { | ||||
|          if (pSession->hConnection) | ||||
|             WinHttpCloseHandle(pSession->hConnection); | ||||
|  | ||||
|          if (pSession->hSession) | ||||
|             WinHttpCloseHandle(pSession->hSession); | ||||
|  | ||||
|          if (pSession->pHostName) | ||||
|             free(pSession->pHostName); | ||||
|  | ||||
|          free(pSession); | ||||
|          pSession = NULL; | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    DbgTrace(2, "-OpenRpcSession- End, pSession = %08X\n", pSession); | ||||
|  | ||||
|    return pSession; | ||||
| } | ||||
|  | ||||
|  | ||||
| //++======================================================================= | ||||
| void | ||||
| CloseRpcSession( | ||||
|    IN    RpcSession *pSession) | ||||
| // | ||||
| //  Arguments:  | ||||
| // | ||||
| //  Returns:    | ||||
| // | ||||
| //  Abstract:   | ||||
| // | ||||
| //  Notes: | ||||
| // | ||||
| // L2 | ||||
| //=======================================================================-- | ||||
| { | ||||
|    DbgTrace(1, "-CloseRpcSession- Start\n", 0); | ||||
|  | ||||
|    // Close the connection handle | ||||
|    WinHttpCloseHandle(pSession->hConnection); | ||||
|  | ||||
|    // Close the session handle | ||||
|    WinHttpCloseHandle(pSession->hSession); | ||||
|  | ||||
|    // Free hostname buffer if necessary | ||||
|    if (pSession->pHostName) | ||||
|       free(pSession->pHostName); | ||||
|  | ||||
|    // Free the space allocated for the session | ||||
|    free(pSession); | ||||
|  | ||||
|    DbgTrace(1, "-CloseRpcSession- End\n", 0); | ||||
| } | ||||
|  | ||||
|  | ||||
| //++======================================================================= | ||||
| static | ||||
| void CALLBACK | ||||
| SecureFailureStatusCallback( | ||||
|    IN    HINTERNET hRequest, | ||||
|    IN    DWORD *pContext, | ||||
|    IN    DWORD internetStatus, | ||||
|    IN    LPVOID pStatusInformation, | ||||
|    IN    DWORD statusInformationLength) | ||||
| // | ||||
| //  Arguments:  | ||||
| // | ||||
| //  Returns:    | ||||
| // | ||||
| //  Abstract:   | ||||
| // | ||||
| //  Notes: | ||||
| // | ||||
| // L0 | ||||
| //=======================================================================-- | ||||
| { | ||||
|    DbgTrace(1, "-SecureFailureStatusCallback- Start\n", 0); | ||||
|  | ||||
|    // Only deal with failures related to certificates | ||||
|    if (internetStatus == WINHTTP_CALLBACK_STATUS_SECURE_FAILURE) | ||||
|    { | ||||
|       // Save the specific failure status | ||||
|       *pContext = *(DWORD*) pStatusInformation; | ||||
|    } | ||||
|  | ||||
|    DbgTrace(1, "-SecureFailureStatusCallback- End\n", 0); | ||||
| } | ||||
|  | ||||
|  | ||||
| //++======================================================================= | ||||
| static | ||||
| CasaStatus | ||||
| InternalRpc( | ||||
|    IN    RpcSession *pSession, | ||||
|    IN    char *pMethod, | ||||
|    IN    long flags, | ||||
|    IN    char *pRequestData, | ||||
|    INOUT char **ppResponseData, | ||||
|    INOUT int *pResponseDataLen) | ||||
| // | ||||
| //  Arguments:  | ||||
| // | ||||
| //  Returns:    | ||||
| // | ||||
| //  Abstract:   | ||||
| // | ||||
| //  Notes: | ||||
| // | ||||
| // L2 | ||||
| //=======================================================================-- | ||||
| { | ||||
| #define CASA_STATUS_INVALID_SERVER_CERTIFICATE CASA_STATUS_UNSUCCESSFUL // temporary until casa_status.h is updated | ||||
|  | ||||
|    CasaStatus  retStatus = CASA_STATUS_SUCCESS; | ||||
|    char        rpcTarget[256]; | ||||
|    LPWSTR      pWideRpcTarget; | ||||
|    int         wideRpcTargetLen; | ||||
|    WCHAR       sendHeaders[] = L"Content-Type: text/html"; | ||||
|    DWORD       securityFailureStatusFlags; | ||||
|    int         retriesAllowed = 1; | ||||
|    bool        attemptRetry; | ||||
|  | ||||
|    DbgTrace(1, "-InternalRpc- Start\n", 0); | ||||
|  | ||||
|    // Initialize output parameter | ||||
|    *ppResponseData = NULL; | ||||
|  | ||||
|    // Create rpc target string and convert it to a wide string | ||||
|    sprintf(rpcTarget, "CasaAuthTokenSvc/Rpc?method=%s", pMethod); | ||||
|    retStatus = CopyMultiToWideAlloc(rpcTarget, | ||||
|                                     (int) strlen(rpcTarget), | ||||
|                                     &pWideRpcTarget, | ||||
|                                     &wideRpcTargetLen); | ||||
|    if (CASA_SUCCESS(retStatus)) | ||||
|    { | ||||
|       HINTERNET   hRequest; | ||||
|  | ||||
|       do | ||||
|       { | ||||
|          // Forget about having been told to retry | ||||
|          attemptRetry = false; | ||||
|  | ||||
|          // Open a request handle | ||||
|          hRequest = WinHttpOpenRequest(pSession->hConnection, | ||||
|                                        L"POST", | ||||
|                                        pWideRpcTarget, | ||||
|                                        NULL, | ||||
|                                        WINHTTP_NO_REFERER, | ||||
|                                        WINHTTP_DEFAULT_ACCEPT_TYPES, | ||||
|                                        flags & SECURE_RPC_FLAG? WINHTTP_FLAG_REFRESH | WINHTTP_FLAG_SECURE : WINHTTP_FLAG_REFRESH); | ||||
|          if (hRequest) | ||||
|          { | ||||
|             int   reqDataLen = (int) strlen(pRequestData); | ||||
|  | ||||
|             // Check if we need to set options to deal with secure connections | ||||
|             if (flags & SECURE_RPC_FLAG) | ||||
|             { | ||||
|                // We are using secure connections, now proceed based on whether or not | ||||
|                // we are configured to allow invalid certificates. | ||||
|                if (flags & ALLOW_INVALID_CERTS_RPC_FLAG | ||||
|                    || (flags & ALLOW_INVALID_CERTS_USER_APPROVAL_RPC_FLAG | ||||
|                        && InvalidCertsFromHostAllowed(pSession->pHostName))) | ||||
|                { | ||||
|                   DWORD secFlags = SECURITY_FLAG_IGNORE_CERT_CN_INVALID | SECURITY_FLAG_IGNORE_UNKNOWN_CA; | ||||
|  | ||||
|                   // We are configured to allow invalid certificates, inform the HTTP stack. | ||||
|                   if (WinHttpSetOption(hRequest, | ||||
|                                        WINHTTP_OPTION_SECURITY_FLAGS, | ||||
|                                        &secFlags, | ||||
|                                        sizeof(secFlags)) == FALSE) | ||||
|                   { | ||||
|                      DbgTrace(0, "-InternalRpc- Failed setting options to ignore invalid certs, error = %d\n", GetLastError()); | ||||
|                   } | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   // We are not configured to allow invalid certificates, set a callback handler | ||||
|                   // to detect invalid certificate conditions. | ||||
|                   if (WinHttpSetStatusCallback(hRequest, | ||||
|                                                SecureFailureStatusCallback, | ||||
|                                                WINHTTP_CALLBACK_FLAG_SECURE_FAILURE, | ||||
|                                                (DWORD_PTR) NULL) == WINHTTP_INVALID_STATUS_CALLBACK) | ||||
|                   { | ||||
|                      DbgTrace(0, "-InternalRpc- Failed setting status callback, error = %d\n", GetLastError()); | ||||
|                   } | ||||
|                } | ||||
|             } | ||||
|  | ||||
|             // Send the request | ||||
|             securityFailureStatusFlags = 0; | ||||
|             if (WinHttpSendRequest(hRequest, | ||||
|                                    sendHeaders, | ||||
|                                    -1, | ||||
|                                    pRequestData, | ||||
|                                    reqDataLen, | ||||
|                                    reqDataLen, | ||||
|                                    (DWORD_PTR) &securityFailureStatusFlags)) | ||||
|             { | ||||
|                // Request sent, now await for the response. | ||||
|                if (WinHttpReceiveResponse(hRequest, NULL)) | ||||
|                { | ||||
|                   WCHAR httpCompStatus[4] = {0}; | ||||
|                   DWORD httpCompStatusLen = sizeof(httpCompStatus); | ||||
|  | ||||
|                   // Response received, make sure that it completed successfully. | ||||
|                   if (WinHttpQueryHeaders(hRequest, | ||||
|                                           WINHTTP_QUERY_STATUS_CODE, | ||||
|                                           NULL, | ||||
|                                           &httpCompStatus, | ||||
|                                           &httpCompStatusLen, | ||||
|                                           WINHTTP_NO_HEADER_INDEX)) | ||||
|                   { | ||||
|                      // Check that the request completed successfully | ||||
|                      if (memcmp(httpCompStatus, L"200", sizeof(httpCompStatus)) == 0) | ||||
|                      { | ||||
|                         char  *pResponseData; | ||||
|                         int   responseDataBufSize = INITIAL_RESPONSE_DATA_BUF_SIZE;       | ||||
|                         int   responseDataRead = 0; | ||||
|  | ||||
|                         // Now read the response data, to do so we need to allocate a buffer. | ||||
|                         pResponseData = (char*) malloc(INITIAL_RESPONSE_DATA_BUF_SIZE); | ||||
|                         if (pResponseData) | ||||
|                         { | ||||
|                            char     *pCurrLocation = pResponseData; | ||||
|                            DWORD    bytesRead; | ||||
|  | ||||
|                            do | ||||
|                            { | ||||
|                               bytesRead = 0; | ||||
|                               if (WinHttpReadData(hRequest, | ||||
|                                                   (LPVOID) pCurrLocation, | ||||
|                                                   responseDataBufSize - responseDataRead, | ||||
|                                                   &bytesRead)) | ||||
|                               { | ||||
|                                  pCurrLocation += bytesRead; | ||||
|                                  responseDataRead += bytesRead; | ||||
|  | ||||
|                                  // Check if we need to allocate a larger buffer | ||||
|                                  if (responseDataRead == responseDataBufSize) | ||||
|                                  { | ||||
|                                     char  *pTmpBuf; | ||||
|  | ||||
|                                     // We need to upgrade the receive buffer | ||||
|                                     pTmpBuf = (char*) malloc(responseDataBufSize + INCREMENT_RESPONSE_DATA_BUF_SIZE); | ||||
|                                     if (pTmpBuf) | ||||
|                                     { | ||||
|                                        memcpy(pTmpBuf, pResponseData, responseDataBufSize); | ||||
|                                        free(pResponseData); | ||||
|                                        pResponseData = pTmpBuf; | ||||
|                                        pCurrLocation = pResponseData + responseDataBufSize; | ||||
|                                        responseDataBufSize += INCREMENT_RESPONSE_DATA_BUF_SIZE; | ||||
|                                     } | ||||
|                                     else | ||||
|                                     { | ||||
|                                        DbgTrace(0, "-InternalRpc- Buffer allocation failure\n", 0); | ||||
|                                        retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, | ||||
|                                                                    CASA_FACILITY_AUTHTOKEN, | ||||
|                                                                    CASA_STATUS_INSUFFICIENT_RESOURCES); | ||||
|                                     } | ||||
|                                  } | ||||
|                               } | ||||
|                               else | ||||
|                               { | ||||
|                                  DbgTrace(0, "-InternalRpc- Failed reading response data, error = %d\n", GetLastError()); | ||||
|                                  retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, | ||||
|                                                              CASA_FACILITY_AUTHTOKEN, | ||||
|                                                              CASA_STATUS_UNSUCCESSFUL); | ||||
|                               } | ||||
|                            } while (CASA_SUCCESS(retStatus) | ||||
|                                     && bytesRead != 0); | ||||
|  | ||||
|                            // Check if the response data was successfully received | ||||
|                            if (CASA_SUCCESS(retStatus)) | ||||
|                            { | ||||
|                               // The response data was received, return it to the caller. | ||||
|                               *ppResponseData = pResponseData; | ||||
|                               *pResponseDataLen = responseDataRead;  | ||||
|                            } | ||||
|                            else | ||||
|                            { | ||||
|                               // Failed to receive the response data, free the allocated buffer. | ||||
|                               free(pResponseData); | ||||
|                            } | ||||
|                         } | ||||
|                         else | ||||
|                         { | ||||
|                            DbgTrace(0, "-InternalRpc- Buffer allocation failure\n", 0); | ||||
|                            retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, | ||||
|                                                        CASA_FACILITY_AUTHTOKEN, | ||||
|                                                        CASA_STATUS_INSUFFICIENT_RESOURCES); | ||||
|                         } | ||||
|                      } | ||||
|                      else | ||||
|                      { | ||||
|                         DbgTrace(0, "-InternalRpc- HTTP request did not complete successfully, status = %S\n", httpCompStatus); | ||||
|                         retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, | ||||
|                                                     CASA_FACILITY_AUTHTOKEN, | ||||
|                                                     CASA_STATUS_UNSUCCESSFUL); | ||||
|                      } | ||||
|                   } | ||||
|                   else | ||||
|                   { | ||||
|                      DbgTrace(0, "-InternalRpc- Unable to obtain http request completion status, error = %d\n", GetLastError()); | ||||
|                      retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, | ||||
|                                                  CASA_FACILITY_AUTHTOKEN, | ||||
|                                                  CASA_STATUS_UNSUCCESSFUL); | ||||
|                   } | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   DbgTrace(0, "-InternalRpc- Unable to receive response, error = %d\n", GetLastError()); | ||||
|                   retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, | ||||
|                                               CASA_FACILITY_AUTHTOKEN, | ||||
|                                               CASA_STATUS_UNSUCCESSFUL); | ||||
|                } | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                int   error = GetLastError(); | ||||
|  | ||||
|                if (error == ERROR_WINHTTP_CANNOT_CONNECT) | ||||
|                { | ||||
|                   DbgTrace(0, "-InternalRpc- Unable to connect to server\n", 0); | ||||
|                   retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, | ||||
|                                               CASA_FACILITY_AUTHTOKEN, | ||||
|                                               CASA_STATUS_AUTH_SERVER_UNAVAILABLE); | ||||
|                } | ||||
|                else if (error == ERROR_WINHTTP_SECURE_FAILURE) | ||||
|                { | ||||
|                   DbgTrace(1, "-InternalRpc- Secure connection failure, flags = %0x\n", securityFailureStatusFlags); | ||||
|  | ||||
|                   // Try to deal with the issue | ||||
|                   if ((securityFailureStatusFlags & ~(WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA | ||||
|                                                       | WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID | ||||
|                                                       | WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID)) == 0 | ||||
|                       && flags & ALLOW_INVALID_CERTS_USER_APPROVAL_RPC_FLAG) | ||||
|                   { | ||||
|                      WINHTTP_CERTIFICATE_INFO certInfo; | ||||
|                      DWORD certInfoLen = sizeof(certInfo); | ||||
|  | ||||
|                      // The failure was due to an invalid CN, CA, or both. | ||||
|                      // | ||||
|                      // Obtain information about the server certificate to give user | ||||
|                      // the choice of accepting it. | ||||
|                      if (WinHttpQueryOption(hRequest, | ||||
|                                             WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT, | ||||
|                                             &certInfo, | ||||
|                                             &certInfoLen) | ||||
|                          && certInfo.lpszSubjectInfo != NULL | ||||
|                          && certInfo.lpszIssuerInfo != NULL) | ||||
|                      { | ||||
|                         char  *pSubjectInfo; | ||||
|                         int   subjectInfoLen; | ||||
|  | ||||
|                         // Convert the subjectInfo to multi-byte | ||||
|                         retStatus = CopyWideToMultiAlloc(certInfo.lpszSubjectInfo, | ||||
|                                                          (int) wcslen(certInfo.lpszSubjectInfo), | ||||
|                                                          &pSubjectInfo, | ||||
|                                                          &subjectInfoLen); | ||||
|                         if (CASA_SUCCESS(retStatus)) | ||||
|                         { | ||||
|                            char  *pIssuerInfo; | ||||
|                            int   issuerInfoLen; | ||||
|  | ||||
|                            // Convert the issuerInfo to multi-byte | ||||
|                            retStatus = CopyWideToMultiAlloc(certInfo.lpszIssuerInfo, | ||||
|                                                             (int) wcslen(certInfo.lpszIssuerInfo), | ||||
|                                                             &pIssuerInfo, | ||||
|                                                             &issuerInfoLen); | ||||
|                            if (CASA_SUCCESS(retStatus)) | ||||
|                            { | ||||
|                               long  invalidCertFlags = 0; | ||||
|  | ||||
|                               // Setup the invalid cert flags | ||||
|                               if (securityFailureStatusFlags & WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA) | ||||
|                                  invalidCertFlags |= INVALID_CERT_CA_FLAG; | ||||
|  | ||||
|                               if (securityFailureStatusFlags & WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID) | ||||
|                                  invalidCertFlags |= INVALID_CERT_CN_FLAG; | ||||
|  | ||||
|                               if (securityFailureStatusFlags & WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID) | ||||
|                                  invalidCertFlags |= INVALID_CERT_DATE_FLAG; | ||||
|  | ||||
|                               // Give user the choice to accept the certificate | ||||
|                               if (UserApprovedCert(pSession->pHostName, | ||||
|                                                    pSubjectInfo, | ||||
|                                                    pIssuerInfo, | ||||
|                                                    invalidCertFlags)) | ||||
|                               { | ||||
|                                  DbgTrace(1, "-InternalRpc- User approved invalid certificate from %s\n", pSession->pHostName); | ||||
|  | ||||
|                                  // tbd - Investigate if there is a way to set the accepted certificate in a store so that | ||||
|                                  // it can be utilized by the SSL stack directly. This would be a better method for dealing with | ||||
|                                  // this issue. | ||||
|  | ||||
|                                  AllowInvalidCertsFromHost(pSession->pHostName); | ||||
|  | ||||
|                                  // Try to retry the request | ||||
|                                  attemptRetry = true; | ||||
|                               } | ||||
|                               else | ||||
|                               { | ||||
|                                  DbgTrace(1, "-InternalRpc- User did not approve invalid certificate from %s\n", pSession->pHostName); | ||||
|  | ||||
|                                  retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, | ||||
|                                                              CASA_FACILITY_AUTHTOKEN, | ||||
|                                                              CASA_STATUS_INVALID_SERVER_CERTIFICATE); | ||||
|                               } | ||||
|  | ||||
|                               // Free the buffer containing the issuerInfo | ||||
|                               free(pIssuerInfo); | ||||
|                            } | ||||
|  | ||||
|                            // Free the buffer containing the subjectInfo | ||||
|                            free(pSubjectInfo); | ||||
|                         } | ||||
|  | ||||
|                         // Free necessary certificate information | ||||
|                         if (certInfo.lpszSubjectInfo) LocalFree(certInfo.lpszSubjectInfo); | ||||
|                         if (certInfo.lpszIssuerInfo) LocalFree(certInfo.lpszIssuerInfo); | ||||
|                         if (certInfo.lpszProtocolName) LocalFree(certInfo.lpszProtocolName); | ||||
|                         if (certInfo.lpszSignatureAlgName) LocalFree(certInfo.lpszSignatureAlgName); | ||||
|                         if (certInfo.lpszEncryptionAlgName) LocalFree(certInfo.lpszEncryptionAlgName); | ||||
|                      } | ||||
|                      else | ||||
|                      { | ||||
|                         DbgTrace(0, "-InternalRpc- Unable to obtain server certificate struct, error = %0x\n", GetLastError()); | ||||
|                      } | ||||
|                   } | ||||
|                   else | ||||
|                   { | ||||
|                      // Decided to no give the user a choice to accept invalid server certificate | ||||
|                      retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, | ||||
|                                                  CASA_FACILITY_AUTHTOKEN, | ||||
|                                                  CASA_STATUS_INVALID_SERVER_CERTIFICATE); | ||||
|                   } | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   DbgTrace(0, "-InternalRpc- Unsuccessful send http request, error = %d\n", error); | ||||
|                   retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, | ||||
|                                               CASA_FACILITY_AUTHTOKEN, | ||||
|                                               CASA_STATUS_UNSUCCESSFUL); | ||||
|                } | ||||
|             } | ||||
|  | ||||
|             // Close the request handle | ||||
|             WinHttpCloseHandle(hRequest); | ||||
|          } | ||||
|          else | ||||
|          { | ||||
|             DbgTrace(0, "-InternalRpc- Unable to open http request, error = %d\n", GetLastError()); | ||||
|             retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, | ||||
|                                         CASA_FACILITY_AUTHTOKEN, | ||||
|                                         CASA_STATUS_UNSUCCESSFUL); | ||||
|          } | ||||
|       } while (attemptRetry && retriesAllowed--); | ||||
|  | ||||
|       // Free the rpc target wide string buffer | ||||
|       free(pWideRpcTarget); | ||||
|    } | ||||
|    else | ||||
|    { | ||||
|       DbgTrace(0, "-InternalRpc- Error converting method name to wide string\n", 0); | ||||
|    } | ||||
|  | ||||
|    DbgTrace(1, "-InternalRpc- End, retStatus = %d\n", retStatus); | ||||
|  | ||||
|    return retStatus; | ||||
| } | ||||
|  | ||||
|  | ||||
| //++======================================================================= | ||||
| CasaStatus | ||||
| Rpc( | ||||
|    IN    RpcSession *pSession, | ||||
|    IN    char *pMethod, | ||||
|    IN    long flags, | ||||
|    IN    char *pRequestData, | ||||
|    INOUT char **ppResponseData, | ||||
|    INOUT int *pResponseDataLen) | ||||
| // | ||||
| //  Arguments:  | ||||
| // | ||||
| //  Returns:    | ||||
| // | ||||
| //  Abstract:   | ||||
| // | ||||
| //  Notes: | ||||
| // | ||||
| // L2 | ||||
| //=======================================================================-- | ||||
| { | ||||
|    CasaStatus  retStatus; | ||||
|    int         retries = 0; | ||||
|  | ||||
|    DbgTrace(1, "-Rpc- Start\n", 0); | ||||
|  | ||||
|    // Retry the RPC as needed | ||||
|    do | ||||
|    { | ||||
|       // Issue the RPC | ||||
|       retStatus = InternalRpc(pSession, | ||||
|                               pMethod, | ||||
|                               flags, | ||||
|                               pRequestData, | ||||
|                               ppResponseData, | ||||
|                               pResponseDataLen); | ||||
|  | ||||
|       // Account for this try | ||||
|       retries ++; | ||||
|  | ||||
|    } while (CasaStatusCode(retStatus) == CASA_STATUS_AUTH_SERVER_UNAVAILABLE | ||||
|             && retries < MAX_RPC_RETRIES); | ||||
|  | ||||
|    DbgTrace(1, "-Rpc- End, retStatus = %d\n", retStatus); | ||||
|  | ||||
|    return retStatus; | ||||
| } | ||||
|  | ||||
|  | ||||
| //++======================================================================= | ||||
| CasaStatus | ||||
| InitializeRpc(void) | ||||
| // | ||||
| //  Arguments:  | ||||
| // | ||||
| //  Returns:    | ||||
| // | ||||
| //  Abstract:   | ||||
| // | ||||
| //  Notes: | ||||
| // | ||||
| // L2 | ||||
| //=======================================================================-- | ||||
| { | ||||
|    CasaStatus  retStatus = CASA_STATUS_SUCCESS; | ||||
|  | ||||
|    DbgTrace(1, "-InitializeRpc- Start\n", 0); | ||||
|  | ||||
|    // Nothing to do for windows | ||||
|  | ||||
|    DbgTrace(1, "-InitializeRpc- End, retStatus = %08X\n", retStatus); | ||||
|  | ||||
|    return retStatus; | ||||
| } | ||||
|  | ||||
|  | ||||
| //++======================================================================= | ||||
| //++======================================================================= | ||||
| //++======================================================================= | ||||
|  | ||||
		Reference in New Issue
	
	Block a user