Splitted the non-java project into client and server projects in order
to be able to deliver the client component onto distributions targeting desktops without having to deliver the server components. This commit is for the resulting client project.
This commit is contained in:
		
							
								
								
									
										69
									
								
								CASA-auth-token/client/core/windows/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								CASA-auth-token/client/core/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/core/windows/authtoken.def
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								CASA-auth-token/client/core/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/core/windows/client.vcproj
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										224
									
								
								CASA-auth-token/client/core/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/core/windows/dllsup.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										233
									
								
								CASA-auth-token/client/core/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/core/windows/platform.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										580
									
								
								CASA-auth-token/client/core/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/core/windows/platform.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								CASA-auth-token/client/core/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/core/windows/rpc.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										799
									
								
								CASA-auth-token/client/core/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