Initializing the SSPI

Before initializing the SSPI, an application must load the security provider using the LoadLibrary function.

The following code example shows how to load the security provider DLL.

HINSTANCE DllHandle;
TCHAR szError[100];

// Load the security provider DLL.
DllHandle = LoadLibrary (TEXT("secur32.dll"));

if (!DllHandle)
{
  wsprintf (szError, 
            TEXT("Failed in loading secur32.dll, Error: %x"),
            GetLastError ());
  return 0;
}

When the SSP has loaded successfully, the client and the server call the GetProcAddress function to get a pointer to InitSecurityInterface, the initialization function for the provider. You can use InitSecurityInterface to return a pointer to the SecurityFunctionTable function. The table contains pointers to SSPI functions implemented by the SSP. A provider may choose not to implement some of the SSPI functions, if the provider does not support the underlying operation.

Before using a specific security package, both client and server must call the EnumerateSecurityPackages function to enumerate the security packages available from the security provider. Applications usually know which provider to use and specify it by name in a call to the AcquireCredentialsHandle function. EnumerateSecurityPackages returns an array of SECPKGINFO structures that describe attributes of the available security packages. A client or server can also use the QuerySecurityPackageInfo function to determine the attributes of the specified security package.

The following code example shows how to initialize the SSPI.

BOOL InitSspi (HINSTANCE DllHandle)
{
  DWORD dwIndex,
        dwNumOfPkgs,
        dwPkgToUse;
  TCHAR szError[100];

  INIT_SECURITY_INTERFACE InitSecurityInterface;
  PSecurityFunctionTable pSecurityInterface = NULL;
  PSecPkgInfo pSecurityPackages = NULL;
  SECURITY_STATUS status;
  ULONG ulCapabilities;

  // Get the address of the InitSecurityInterface function.
  InitSecurityInterface = (INIT_SECURITY_INTERFACE) GetProcAddress (
                                        DllHandle, 
                                        TEXT("InitSecurityInterfaceW"));

  if (!InitSecurityInterface)
  {
    wsprintf (szError, 
              TEXT("Failed in getting the function address, Error: %x"),
              GetLastError ());
    return FALSE;
  }

  // Use InitSecurityInterface to get the function table.
  pSecurityInterface = (*InitSecurityInterface)();

  if (!pSecurityInterface)
  {
    wsprintf (szError, 
              TEXT("Failed in getting the function table, Error: %x"),
              GetLastError ());
    return FALSE;
  }

  if (!(pSecurityInterface->EnumerateSecurityPackages))
  {
    wsprintf (szError, 
              TEXT("Failed in getting the function table, Error: %x"),
              GetLastError ());
    return FALSE;
  }

  // Retrieve security packages supported by the provider.
  status = (*pSecurityInterface->EnumerateSecurityPackages)(
                                                    &dwNumOfPkgs, 
                                                    &pSecurityPackages);
  if (status != SEC_E_OK)
  {
    wsprintf (szError, 
              TEXT("Failed in retrieving security packages, Error: %x"),
              GetLastError ());
    return FALSE;
  }

  // Initialize dwPkgToUse. 
  dwPkgToUse = -1;

  // Assume the application requires integrity, privacy, and
  // impersonation on messages.
  ulCapabilities = SECPKG_FLAG_INTEGRITY | SECPKG_FLAG_PRIVACY | 
                   SECPKG_FLAG_IMPERSONATION;

  // Determine which package should be used.
  for (dwIndex = 0; dwIndex < dwNumOfPkgs; dwIndex++)
  {
    if ((pSecurityPackages[dwIndex].fCapabilities & ulCapabilities) ==
        ulCapabilities)
    {
      dwPkgToUse = dwIndex;
      break;
    }
  }

  if (!AuthConn (pSecurityInterface, pSecurityPackages, dwPkgToUse))
  {
    MessageBox (NULL, 
                TEXT("Failed in authenticating a connection."),
                TEXT("Error"),
                MB_OK);
    return FALSE;
  }
  
  return TRUE;
}