Once the provider has been loaded successfully, you need to perform some setup to use the security interface conveniently in the rest of the application. First, you need to get a pointer to the initialization function for the provider. Then you will use the initialization function to get a reference to the provider's security function table. Finally, you can get information from the provider about the security packages, or protocols, supported by this security provider. Each security package may have unique capabilities of interest to the application. However, in most cases, applications use security packages that support default or common capabilities.
The example below shows how to initialize the security provider.
// // Initial provider setup. // INIT_SECURITY_INTERFACE InitSecurityInterface; PSecurityFunctionTable SecurityInterface = 0; SecPkgInfo PAPI * SecurityPackages; DWORD NumOfPkgs; SECURITY_PROVIDER_INFO PAPI * List; InitSecurityInterface = GetProcAddress(DllHandle, SECURITY_ENDPOINT); if(!InitSecurityInterface) { // // Something is amiss.. // } // // We got the InitSecurityInterface! // Now use it to get the function table. // SecurityInterface = (*InitSecurityInterface)(); if(!SecurityInterface) { // // we have a problem… // } // // Lets find out the security packages supported by the provider. // Status = (*SecurityInterface->EnumerateSecurityPackages)( &NumOfPkgs, &SecurityPackages); // // Now using the capabilities information figure out which package you want to use. // PkgToUseIndex = -1; for(I=0;I<NumOfPackages;I++) { // // for example, if app needs integrity & privacy on messages, it checks // if(SecurityPackages[I].fCapabilities & (SECPKG_FLAG_INTEGRITY | SECPKG_FLAG_PRIVACY)) { PkgToUseIndex = I; break; } } if(PkgToUseIndex > 0) { // // Find out the maximum token size for this package // g_MaxToken = SecurityPackages[I].cbMaxToken; }
Both the client and server need to agree on the security package they will use before the SSPI initialization steps shown above. The next release of
Windows NT will to support security package negotiation that takes place automatically by the security provider.
At this point the application has successfully initialized a security support provider and chosen a security package with sufficient capabilities needed by the application protocol. The SecurityInterface points to an array of function pointers as defined by SSPI.
Notice that the call to EnumerateSecurityPackages initializes the reference pointer SecurityPackages, with return data. Some SSPI functions have return output parameters, such as security package information. For the output data parameters, the caller passes in a pointer to a pointer to the return structure type, and the security provider allocates memory and returns the data to the caller by assigning the address of the return data buffer to the argument. The convention used by SSPI to return data is the following:
"The security package allocates, and the caller frees."
Therefore, the calling program will use FreeContextBuffer to free the memory containing data allocated by the security provider when it is done referencing the data. The examples below will continue to reference SecurityPackages information, so it must be freed later.