SSPI - система единого внутреннего планаирования
SSPI (Security Support Provider Interface) - это набор API (Application Programming Interface), разработанный компанией Microsoft, который предоставляет способ установления безопасного соединения и аутентификации между клиентом и сервером.
SSPI позволяет приложениям использовать различные механизмы безопасности, такие как Kerberos, NTLM и др., для обеспечения аутентификации клиента и сервера перед установлением соединения между ними.
Код, использующий SSPI для аутентификации и установления безопасного соединения, может выглядеть следующим образом на языке C++:
cpp
#include
#include
int main()
{
// Инициализация SSPI
SECURITY_STATUS status;
SecPkgInfo package_info;
status = QuerySecurityPackageInfo("Negotiate", &package_info);
if (status != SEC_E_OK)
{
// Обработка ошибки
return -1;
}
// Установка соединения
CredHandle client_creds;
CtxtHandle context;
SECURITY_INTEGER expiry;
unsigned long attributes;
status = AcquireCredentialsHandle(NULL, package_info.Name, SECPKG_CRED_OUTBOUND, NULL, NULL, NULL, NULL, &client_creds, &expiry);
if (status != SEC_E_OK)
{
// Обработка ошибки
return -1;
}
// Запуск процесса аутентификации
SecBufferDesc input_buffers;
SecBufferDesc output_buffers;
SecBuffer input_buffer;
SecBuffer output_buffer;
ULONG context_attributes;
DWORD context_req = ISC_REQ_MUTUAL_AUTH | ISC_REQ_USE_SESSION_KEY;
DWORD context_ret;
while (true)
{
// Генерация буфера для отправки на сервер
input_buffers.ulVersion = SECBUFFER_VERSION;
input_buffers.cBuffers = 1;
input_buffers.pBuffers = &input_buffer;
input_buffer.BufferType = SECBUFFER_TOKEN;
input_buffer.cbBuffer = 0;
input_buffer.pvBuffer = NULL;
// Генерация буфера для получения ответа от сервера
output_buffers.ulVersion = SECBUFFER_VERSION;
output_buffers.cBuffers = 1;
output_buffers.pBuffers = &output_buffer;
output_buffer.BufferType = SECBUFFER_TOKEN;
output_buffer.cbBuffer = 0;
output_buffer.pvBuffer = NULL;
// Процесс аутентификации
status = InitializeSecurityContext(&client_creds, NULL, NULL, context_req, 0, SECURITY_NATIVE_DREP, NULL, 0, &context, &output_buffers, &context_attributes, &expiry);
if (status == SEC_I_CONTINUE_NEEDED)
{
// Отправка буфера на сервер и получение ответа
// ...
// Обновление контекста аутентификации
status = InitializeSecurityContext(&client_creds, &context, NULL, context_req, 0, SECURITY_NATIVE_DREP, &output_buffers, 0, &context, &output_buffers, &context_attributes, &expiry);
if (status != SEC_E_OK)
{
// Обработка ошибки
return -1;
}
}
else if (status != SEC_E_OK)
{
// Обработка ошибки
return -1;
}
// Завершение процесса аутентификации
status = CompleteAuthToken(&context, &output_buffers);
if (status != SEC_E_OK)
{
// Обработка ошибки
return -1;
}
// Выход из цикла, если аутентификация успешна
if (status == SEC_E_OK)
{
break;
}
}
// ...
// Очистка ресурсов SSPI
status = DeleteSecurityContext(&context);
if (status != SEC_E_OK)
{
// Обработка ошибки
return -1;
}
status = FreeCredentialsHandle(&client_creds);
if (status != SEC_E_OK)
{
// Обработка ошибки
return -1;
}
return 0;
}
В данном примере кода используется функция `QuerySecurityPackageInfo`, чтобы получить информацию о доступных пакетах безопасности, и функция `AcquireCredentialsHandle`, чтобы получить handle для установки соединения с сервером.
Далее, в цикле производится аутентификация клиента с помощью функций `InitializeSecurityContext` и `CompleteAuthToken`, пока аутентификация не будет успешно завершена (`SEC_E_OK`).
В конце кода происходит очистка ресурсов SSPI с помощью функций `DeleteSecurityContext` и `FreeCredentialsHandle`.
SSPI предоставляет удобную абстракцию для работы с безопасностью в приложениях, позволяя использовать различные механизмы аутентификации и шифрования без необходимости в прямой работе с низкоуровневыми протоколами и библиотеками.