initial commit for kerberos support

This commit is contained in:
dodo040 2017-05-11 18:51:45 +02:00 committed by Armin Novak
parent ff59cf028c
commit b81f168f0e
27 changed files with 3208 additions and 400 deletions

View File

@ -674,14 +674,14 @@ set(OPENH264_FEATURE_TYPE "OPTIONAL")
set(OPENH264_FEATURE_PURPOSE "codec")
set(OPENH264_FEATURE_DESCRIPTION "use OpenH264 library")
set(KRB5_FEATURE_TYPE "OPTIONAL")
set(KRB5_FEATURE_PURPOSE "auth")
set(KRB5_FEATURE_DESCRIPTION "add kerberos support")
set(GSM_FEATURE_TYPE "OPTIONAL")
set(GSM_FEATURE_PURPOSE "codec")
set(GSM_FEATURE_DESCRIPTION "GSM audio codec library")
set(GSSAPI_FEATURE_TYPE "OPTIONAL")
set(GSSAPI_FEATURE_PURPOSE "auth")
set(GSSAPI_FEATURE_DESCRIPTION "add kerberos support")
if(WIN32)
set(X11_FEATURE_TYPE "DISABLED")
set(WAYLAND_FEATURE_TYPE "DISABLED")
@ -775,7 +775,22 @@ find_feature(JPEG ${JPEG_FEATURE_TYPE} ${JPEG_FEATURE_PURPOSE} ${JPEG_FEATURE_DE
find_feature(x264 ${X264_FEATURE_TYPE} ${X264_FEATURE_PURPOSE} ${X264_FEATURE_DESCRIPTION})
find_feature(OpenH264 ${OPENH264_FEATURE_TYPE} ${OPENH264_FEATURE_PURPOSE} ${OPENH264_FEATURE_DESCRIPTION})
find_feature(GSM ${GSM_FEATURE_TYPE} ${GSM_FEATURE_PURPOSE} ${GSM_FEATURE_DESCRIPTION})
find_feature(KRB5 ${KRB5_FEATURE_TYPE} ${KRB5_FEATURE_PURPOSE} ${KRB5_FEATURE_DESCRIPTION})
find_feature(GSSAPI ${GSSAPI_FEATURE_TYPE} ${GSSAPI_FEATURE_PURPOSE} ${GSSAPI_FEATURE_DESCRIPTION})
if ( (WITH_GSSAPI) AND (NOT GSS_FOUND))
message(WARNING "-DWITH_GSSAPI=ON is set, but not GSSAPI implementation was found, disabling")
else()
if(GSS_FLAVOUR STREQUAL "MIT")
message(STATUS "MIT Kerberos suppport")
add_definitions("-DWITH_GSSAPI -DWITH_GSSAPI_MIT")
elseif(GSS_FLAVOUR STREQUAL "HEIMDAL")
message(STATUS "Heimdal Kerberos support")
add_definitions("-DWITH_GSSAPI -DWITH_GSSAPI_HEIMDAL")
else()
message(STATUS "Kerberos version not detected")
endif()
endif()
if(TARGET_ARCH MATCHES "x86|x64")
if (NOT APPLE)

View File

@ -2,7 +2,7 @@ message("PRELOADING cache")
set (WITH_MANPAGES OFF CACHE BOOL "man pages")
set (CMAKE_BUILD_TYPE "Debug" CACHE STRING "build type")
set (WITH_CUPS OFF CACHE BOOL "CUPS printing")
set (WITH_KRB5 ON CACHE BOOL "Kerberos support")
set (WITH_GSSAPI ON CACHE BOOL "Kerberos support")
set (WITH_ALSA OFF CACHE BOOL "alsa audio")
set (WITH_FFMPEG OFF CACHE BOOL "ffmepg support")
set (WITH_XV OFF CACHE BOOL "xvideo support")

View File

@ -7,7 +7,7 @@ set (WITH_PULSE ON CACHE BOOL "pulse")
set (WITH_CHANNELS ON CACHE BOOL "channels")
set (BUILTIN_CHANNELS ON CACHE BOOL "static channels")
set (WITH_CUPS ON CACHE BOOL "cups")
set (WITH_KRB5 ON CACHE BOOL "Kerberos support")
set (WITH_GSSAPI ON CACHE BOOL "Kerberos support")
set (WITH_PCSC ON CACHE BOOL "PCSC")
set (WITH_JPEG ON CACHE BOOL "jepg")
set (WITH_GSTREAMER_0_10 ON CACHE BOOL "gstreamer")

View File

@ -2,7 +2,7 @@ message("PRELOADING cache")
set (WITH_MANPAGES OFF CACHE BOOL "man pages")
set (CMAKE_BUILD_TYPE "Debug" CACHE STRING "build type")
set (WITH_CUPS OFF CACHE BOOL "CUPS printing")
set (WITH_KRB5 ON CACHE BOOL "Kerberos support")
set (WITH_GSSAPI ON CACHE BOOL "Kerberos support")
set (WITH_ALSA OFF CACHE BOOL "alsa audio")
set (WITH_FFMPEG OFF CACHE BOOL "ffmepg support")
set (WITH_XV OFF CACHE BOOL "xvideo support")

288
cmake/FindGSSAPI.cmake Normal file
View File

@ -0,0 +1,288 @@
# - Try to find the GSS Kerberos library
# Once done this will define
#
# GSS_ROOT_DIR - Set this variable to the root installation of GSS
#
# Read-Only variables:
# GSS_FOUND - system has the Heimdal library
# GSS_FLAVOUR - "MIT" or "Heimdal" if anything found.
# GSS_INCLUDE_DIR - the Heimdal include directory
# GSS_LIBRARIES - The libraries needed to use GSS
# GSS_LINK_DIRECTORIES - Directories to add to linker search path
# GSS_LINKER_FLAGS - Additional linker flags
# GSS_COMPILER_FLAGS - Additional compiler flags
# GSS_VERSION - This is set to version advertised by pkg-config or read from manifest.
# In case the library is found but no version info availabe it'll be set to "unknown"
set(_MIT_MODNAME mit-krb5-gssapi)
set(_HEIMDAL_MODNAME heimdal-gssapi)
include(CheckIncludeFile)
include(CheckIncludeFiles)
include(CheckTypeSize)
set(_GSS_ROOT_HINTS
"${GSS_ROOT_DIR}"
"$ENV{GSS_ROOT_DIR}"
)
# try to find library using system pkg-config if user didn't specify root dir
if(NOT GSS_ROOT_DIR AND NOT "$ENV{GSS_ROOT_DIR}")
if(UNIX)
find_package(PkgConfig QUIET)
pkg_search_module(_GSS_PKG ${_MIT_MODNAME} ${_HEIMDAL_MODNAME})
list(APPEND _GSS_ROOT_HINTS "${_GSS_PKG_PREFIX}")
elseif(WIN32)
list(APPEND _GSS_ROOT_HINTS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MIT\\Kerberos;InstallDir]")
endif()
endif()
if(NOT _GSS_FOUND) #not found by pkg-config. Let's take more traditional approach.
find_file(_GSS_CONFIGURE_SCRIPT
NAMES
"krb5-config"
HINTS
${_GSS_ROOT_HINTS}
PATH_SUFFIXES
bin
NO_CMAKE_PATH
NO_CMAKE_ENVIRONMENT_PATH
)
# if not found in user-supplied directories, maybe system knows better
find_file(_GSS_CONFIGURE_SCRIPT
NAMES
"krb5-config"
PATH_SUFFIXES
bin
)
if(_GSS_CONFIGURE_SCRIPT)
execute_process(
COMMAND ${_GSS_CONFIGURE_SCRIPT} "--cflags" "gssapi"
OUTPUT_VARIABLE _GSS_CFLAGS
RESULT_VARIABLE _GSS_CONFIGURE_FAILED
)
if(NOT _GSS_CONFIGURE_FAILED) # 0 means success
# should also work in an odd case when multiple directories are given
string(STRIP "${_GSS_CFLAGS}" _GSS_CFLAGS)
string(REGEX REPLACE " +-I" ";" _GSS_CFLAGS "${_GSS_CFLAGS}")
string(REGEX REPLACE " +-([^I][^ \\t;]*)" ";-\\1" _GSS_CFLAGS "${_GSS_CFLAGS}")
foreach(_flag ${_GSS_CFLAGS})
if(_flag MATCHES "^-I.*")
string(REGEX REPLACE "^-I" "" _val "${_flag}")
list(APPEND _GSS_INCLUDE_DIR "${_val}")
else()
list(APPEND _GSS_COMPILER_FLAGS "${_flag}")
endif()
endforeach()
endif()
execute_process(
COMMAND ${_GSS_CONFIGURE_SCRIPT} "--libs" "gssapi"
OUTPUT_VARIABLE _GSS_LIB_FLAGS
RESULT_VARIABLE _GSS_CONFIGURE_FAILED
)
if(NOT _GSS_CONFIGURE_FAILED) # 0 means success
# this script gives us libraries and link directories. Blah. We have to deal with it.
# string(STRIP "krb5support ${_GSS_LIB_FLAGS}" _GSS_LIB_FLAGS)
string(STRIP "${_GSS_LIB_FLAGS}" _GSS_LIB_FLAGS)
string(REGEX REPLACE " +-(L|l)" ";-\\1" _GSS_LIB_FLAGS "${_GSS_LIB_FLAGS}")
string(REGEX REPLACE " +-([^Ll][^ \\t;]*)" ";-\\1" _GSS_LIB_FLAGS "${_GSS_LIB_FLAGS}")
foreach(_flag ${_GSS_LIB_FLAGS})
if(_flag MATCHES "^-l.*")
string(REGEX REPLACE "^-l" "" _val "${_flag}")
list(APPEND _GSS_LIBRARIES "${_val}")
elseif(_flag MATCHES "^-L.*")
string(REGEX REPLACE "^-L" "" _val "${_flag}")
list(APPEND _GSS_LINK_DIRECTORIES "${_val}")
else()
list(APPEND _GSS_LINKER_FLAGS "${_flag}")
endif()
endforeach()
endif()
execute_process(
COMMAND ${_GSS_CONFIGURE_SCRIPT} "--version"
OUTPUT_VARIABLE _GSS_VERSION
RESULT_VARIABLE _GSS_CONFIGURE_FAILED
)
# older versions may not have the "--version" parameter. In this case we just don't care.
if(_GSS_CONFIGURE_FAILED)
set(_GSS_VERSION 0)
endif()
execute_process(
COMMAND ${_GSS_CONFIGURE_SCRIPT} "--vendor"
OUTPUT_VARIABLE _GSS_VENDOR
RESULT_VARIABLE _GSS_CONFIGURE_FAILED
)
# older versions may not have the "--vendor" parameter. In this case we just don't care.
if(_GSS_CONFIGURE_FAILED)
set(GSS_FLAVOUR "Heimdal") # most probably, shouldn't really matter
else()
if(_GSS_VENDOR MATCHES ".*H|heimdal.*")
set(GSS_FLAVOUR "Heimdal")
else()
set(GSS_FLAVOUR "MIT")
endif()
endif()
else() # either there is no config script or we are on platform that doesn't provide one (Windows?)
find_path(_GSS_INCLUDE_DIR
NAMES
"gssapi/gssapi.h"
HINTS
${_GSS_ROOT_HINTS}
PATH_SUFFIXES
include
inc
)
if(_GSS_INCLUDE_DIR) #jay, we've found something
set(CMAKE_REQUIRED_INCLUDES "${_GSS_INCLUDE_DIR}")
check_include_files( "gssapi/gssapi_generic.h;gssapi/gssapi_krb5.h" _GSS_HAVE_MIT_HEADERS)
if(_GSS_HAVE_MIT_HEADERS)
set(GSS_FLAVOUR "MIT")
else()
# prevent compiling the header - just check if we can include it
set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -D__ROKEN_H__")
check_include_file( "roken.h" _GSS_HAVE_ROKEN_H)
check_include_file( "heimdal/roken.h" _GSS_HAVE_HEIMDAL_ROKEN_H)
if(_GSS_HAVE_ROKEN_H OR _GSS_HAVE_HEIMDAL_ROKEN_H)
set(GSS_FLAVOUR "Heimdal")
endif()
set(CMAKE_REQUIRED_DEFINITIONS "")
endif()
else()
# I'm not convinced if this is the right way but this is what autotools do at the moment
find_path(_GSS_INCLUDE_DIR
NAMES
"gssapi.h"
HINTS
${_GSS_ROOT_HINTS}
PATH_SUFFIXES
include
inc
)
if(_GSS_INCLUDE_DIR)
set(GSS_FLAVOUR "Heimdal")
endif()
endif()
# if we have headers, check if we can link libraries
if(GSS_FLAVOUR)
set(_GSS_LIBDIR_SUFFIXES "")
set(_GSS_LIBDIR_HINTS ${_GSS_ROOT_HINTS})
get_filename_component(_GSS_CALCULATED_POTENTIAL_ROOT "${_GSS_INCLUDE_DIR}" PATH)
list(APPEND _GSS_LIBDIR_HINTS ${_GSS_CALCULATED_POTENTIAL_ROOT})
if(WIN32)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
list(APPEND _GSS_LIBDIR_SUFFIXES "lib/AMD64")
if(GSS_FLAVOUR STREQUAL "MIT")
set(_GSS_LIBNAME "gssapi64")
else()
set(_GSS_LIBNAME "libgssapi")
endif()
else()
list(APPEND _GSS_LIBDIR_SUFFIXES "lib/i386")
if(GSS_FLAVOUR STREQUAL "MIT")
set(_GSS_LIBNAME "gssapi32")
else()
set(_GSS_LIBNAME "libgssapi")
endif()
endif()
else()
list(APPEND _GSS_LIBDIR_SUFFIXES "lib;lib64") # those suffixes are not checked for HINTS
if(GSS_FLAVOUR STREQUAL "MIT")
set(_GSS_LIBNAME "gssapi_krb5")
else()
set(_GSS_LIBNAME "gssapi")
endif()
endif()
find_library(_GSS_LIBRARIES
NAMES
${_GSS_LIBNAME}
HINTS
${_GSS_LIBDIR_HINTS}
PATH_SUFFIXES
${_GSS_LIBDIR_SUFFIXES}
)
endif()
endif()
else()
if(_GSS_PKG_${_MIT_MODNAME}_VERSION)
set(GSS_FLAVOUR "MIT")
set(_GSS_VERSION _GSS_PKG_${_MIT_MODNAME}_VERSION)
else()
set(GSS_FLAVOUR "Heimdal")
set(_GSS_VERSION _GSS_PKG_${_MIT_HEIMDAL}_VERSION)
endif()
endif()
set(GSS_INCLUDE_DIR ${_GSS_INCLUDE_DIR})
set(GSS_LIBRARIES ${_GSS_LIBRARIES})
set(GSS_LINK_DIRECTORIES ${_GSS_LINK_DIRECTORIES})
set(GSS_LINKER_FLAGS ${_GSS_LINKER_FLAGS})
set(GSS_COMPILER_FLAGS ${_GSS_COMPILER_FLAGS})
set(GSS_VERSION ${_GSS_VERSION})
if(GSS_FLAVOUR)
if(NOT GSS_VERSION AND GSS_FLAVOUR STREQUAL "Heimdal")
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(HEIMDAL_MANIFEST_FILE "Heimdal.Application.amd64.manifest")
else()
set(HEIMDAL_MANIFEST_FILE "Heimdal.Application.x86.manifest")
endif()
if(EXISTS "${GSS_INCLUDE_DIR}/${HEIMDAL_MANIFEST_FILE}")
file(STRINGS "${GSS_INCLUDE_DIR}/${HEIMDAL_MANIFEST_FILE}" heimdal_version_str
REGEX "^.*version=\"[0-9]\\.[^\"]+\".*$")
string(REGEX MATCH "[0-9]\\.[^\"]+"
GSS_VERSION "${heimdal_version_str}")
endif()
if(NOT GSS_VERSION)
set(GSS_VERSION "Heimdal Unknown")
endif()
elseif(NOT GSS_VERSION AND GSS_FLAVOUR STREQUAL "MIT")
get_filename_component(_MIT_VERSION "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MIT\\Kerberos\\SDK\\CurrentVersion;VersionString]" NAME CACHE)
if(WIN32 AND _MIT_VERSION)
set(GSS_VERSION "${_MIT_VERSION}")
else()
set(GSS_VERSION "MIT Unknown")
endif()
endif()
endif()
include(FindPackageHandleStandardArgs)
set(_GSS_REQUIRED_VARS GSS_LIBRARIES GSS_FLAVOUR)
find_package_handle_standard_args(GSS
REQUIRED_VARS
${_GSS_REQUIRED_VARS}
VERSION_VAR
GSS_VERSION
FAIL_MESSAGE
"Could NOT find GSS, try to set the path to GSS root folder in the system variable GSS_ROOT_DIR"
)
mark_as_advanced(GSS_INCLUDE_DIR GSS_LIBRARIES)

View File

@ -1,28 +0,0 @@
# - Try to find krb5
# Once done this will define
# KRB5_FOUND - pcsc was found
# KRB5_INCLUDE_DIRS - pcsc include directories
# KRB5_LIBRARIES - libraries needed for linking
include(FindPkgConfig)
if(PKG_CONFIG_FOUND)
pkg_check_modules(PC_KRB5 QUIET libkrb5)
endif()
find_path(KRB5_INCLUDE_DIR krb5.h
HINTS ${PC_KRB5_INCLUDEDIR} ${PC_KRB5_INCLUDE_DIRS}
PATH_SUFFIXES KRB5)
find_library(KRB5_LIBRARY NAMES krb5
HINTS ${PC_KRB5_LIBDIR} ${PC_KRB5_LIBRARY_DIRS})
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(KRB5 DEFAULT_MSG KRB5_LIBRARY KRB5_INCLUDE_DIR)
set(KRB5_LIBRARIES ${KRB5_LIBRARY})
set(KRB5_INCLUDE_DIRS ${KRB5_INCLUDE_DIR})
mark_as_advanced(KRB5_INCLUDE_DIR KRB5_LIBRARY)

View File

@ -61,7 +61,6 @@
/* Plugins */
#cmakedefine BUILTIN_CHANNELS
#cmakedefine WITH_RDPDR
#cmakedefine WITH_KRB5
/* Debug */
#cmakedefine WITH_DEBUG_CERTIFICATE

View File

@ -21,7 +21,6 @@ set(MODULE_PREFIX "FREERDP_CORE")
freerdp_definition_add(-DEXT_PATH="${FREERDP_EXTENSION_PATH}")
freerdp_include_directory_add(${OPENSSL_INCLUDE_DIR})
freerdp_include_directory_add(${KRB5_INCLUDE_DIRS})
set(${MODULE_PREFIX}_GATEWAY_DIR "gateway")
@ -141,10 +140,6 @@ endif()
freerdp_library_add(${OPENSSL_LIBRARIES})
if (WITH_KRB5)
freerdp_library_add(${KRB5_LIBRARIES})
endif(WITH_KRB5)
if(BUILD_TESTING)
add_subdirectory(test)
endif()

View File

@ -49,7 +49,7 @@ BOOL ntlm_client_init(rdpNtlm* ntlm, BOOL http, char* user, char* domain, char*
sspi_SetAuthIdentity(&(ntlm->identity), user, domain, password);
status = ntlm->table->QuerySecurityPackageInfo(NTLMSP_NAME, &ntlm->pPackageInfo);
status = ntlm->table->QuerySecurityPackageInfo(NTLMSSP_NAME, &ntlm->pPackageInfo);
if (status != SEC_E_OK)
{
@ -60,7 +60,7 @@ BOOL ntlm_client_init(rdpNtlm* ntlm, BOOL http, char* user, char* domain, char*
ntlm->cbMaxToken = ntlm->pPackageInfo->cbMaxToken;
status = ntlm->table->AcquireCredentialsHandle(NULL, NTLMSP_NAME,
status = ntlm->table->AcquireCredentialsHandle(NULL, NTLMSSP_NAME,
SECPKG_CRED_OUTBOUND, NULL, &ntlm->identity, NULL, NULL,
&ntlm->credentials, &ntlm->expiration);

View File

@ -1,11 +1,12 @@
/**
* WinPR: Windows Portable Runtime
* FreeRDP: A Remote Desktop Protocol Implementation
* Network Level Authentication (NLA)
*
* Copyright 2010-2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
* Copyright 2015 Thincast Technologies GmbH
* Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
* Copyright 2016 Martin Fleisz <martin.fleisz@thincast.com>
* Copyright 2017 Dorian Ducournau <dorian.ducournau@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -94,7 +95,7 @@
*
*/
#define NLA_PKG_NAME NEGOSSP_NAME
#define NLA_PKG_NAME NEGO_SSP_NAME
#define TERMSRV_SPN_PREFIX "TERMSRV/"
@ -116,6 +117,7 @@ void nla_identity_free(SEC_WINNT_AUTH_IDENTITY* identity)
{
if (identity)
{
/* Password authentication */
if (identity->User)
{
memset(identity->User, 0, identity->UserLength * 2);
@ -139,7 +141,7 @@ void nla_identity_free(SEC_WINNT_AUTH_IDENTITY* identity)
}
/**
* Initialize NTLMSSP authentication module (client).
* Initialize NTLM/Kerberos SSP authentication module (client).
* @param credssp
*/
@ -159,7 +161,7 @@ static int nla_client_init(rdpNla* nla)
settings->DisableCredentialsDelegation = TRUE;
if ((!settings->Password) || (!settings->Username)
|| (!strlen(settings->Username)))
|| (!strlen(settings->Password)) || (!strlen(settings->Username)))
{
PromptPassword = TRUE;
}
@ -220,8 +222,11 @@ static int nla_client_init(rdpNla* nla)
nla->identity = NULL;
}
else
sspi_SetAuthIdentity(nla->identity, settings->Username, settings->Domain,
settings->Password);
{
if (sspi_SetAuthIdentity(nla->identity, settings->Username, settings->Domain,
settings->Password) < 0)
return -1;
}
#ifndef _WIN32
{
@ -262,7 +267,7 @@ static int nla_client_init(rdpNla* nla)
if (!sspi_SecBufferAlloc(&nla->PublicKey, tls->PublicKeyLength))
{
WLog_ERR(TAG, "Failed to allocate sspic secBuffer");
WLog_ERR(TAG, "Failed to allocate sspi secBuffer");
return -1;
}
@ -282,6 +287,17 @@ static int nla_client_init(rdpNla* nla)
nla->ServicePrincipalName = spn;
#endif
nla->table = InitSecurityInterfaceEx(0);
#ifdef WITH_GSSAPI /* KERBEROS SSP */
nla->status = nla->table->QuerySecurityPackageInfo(KERBEROS_SSP_NAME, &nla->pPackageInfo);
if (nla->status != SEC_E_OK)
{
WLog_ERR(TAG, "QuerySecurityPackageInfo status %s [0x%08"PRIX32"]",
GetSecurityStatusString(nla->status), nla->status);
return -1;
}
#else /* NTLM SSP */
nla->status = nla->table->QuerySecurityPackageInfo(NLA_PKG_NAME, &nla->pPackageInfo);
if (nla->status != SEC_E_OK)
@ -291,7 +307,11 @@ static int nla_client_init(rdpNla* nla)
return -1;
}
#endif
nla->cbMaxToken = nla->pPackageInfo->cbMaxToken;
nla->packageName = nla->pPackageInfo->Name;
WLog_DBG(TAG, "%s %"PRIu32" : packageName=%s ; cbMaxToken=%d", __FUNCTION__, __LINE__,
nla->packageName, nla->cbMaxToken);
nla->status = nla->table->AcquireCredentialsHandle(NULL, NLA_PKG_NAME,
SECPKG_CRED_OUTBOUND, NULL, nla->identity, NULL, NULL, &nla->credentials,
&nla->expiration);
@ -345,6 +365,32 @@ int nla_client_begin(rdpNla* nla)
WLog_VRB(TAG, " InitializeSecurityContext status %s [0x%08"PRIX32"]",
GetSecurityStatusString(nla->status), nla->status);
/* Handle kerberos context initialization failure.
* After kerberos failed initialize NTLM context */
if (nla->status == SEC_E_NO_CREDENTIALS)
{
nla->status = nla->table->InitializeSecurityContext(&nla->credentials,
NULL, nla->ServicePrincipalName, nla->fContextReq, 0,
SECURITY_NATIVE_DREP, NULL, 0, &nla->context,
&nla->outputBufferDesc, &nla->pfContextAttr, &nla->expiration);
WLog_VRB(TAG, " InitializeSecurityContext status %s [0x%08"PRIX32"]",
GetSecurityStatusString(nla->status), nla->status);
if (nla->status)
{
SECURITY_STATUS status = nla->table->QuerySecurityPackageInfo(NTLM_SSP_NAME, &nla->pPackageInfo);
if (status != SEC_E_OK)
{
WLog_ERR(TAG, "QuerySecurityPackageInfo status %s [0x%08"PRIX32"]",
GetSecurityStatusString(nla->status), status);
return -1;
}
nla->cbMaxToken = nla->pPackageInfo->cbMaxToken;
nla->packageName = nla->pPackageInfo->Name;
}
}
if ((nla->status == SEC_I_COMPLETE_AND_CONTINUE) || (nla->status == SEC_I_COMPLETE_NEEDED))
{
if (nla->table->CompleteAuthToken)
@ -719,28 +765,32 @@ static int nla_server_authenticate(rdpNla* nla)
if ((nla->status == SEC_I_COMPLETE_AND_CONTINUE) || (nla->status == SEC_I_COMPLETE_NEEDED))
{
freerdp_peer *peer = nla->instance->context->peer;
freerdp_peer* peer = nla->instance->context->peer;
if (peer->ComputeNtlmHash)
{
SECURITY_STATUS status;
status = nla->table->SetContextAttributes(&nla->context, SECPKG_ATTR_AUTH_NTLM_HASH_CB,
peer->ComputeNtlmHash, 0);
status = nla->table->SetContextAttributes(&nla->context, SECPKG_ATTR_AUTH_NTLM_HASH_CB, peer->ComputeNtlmHash, 0);
if (status != SEC_E_OK)
{
WLog_ERR(TAG, "SetContextAttributesA(hash cb) status %s [0x%08"PRIX32"]", GetSecurityStatusString(status), status);
WLog_ERR(TAG, "SetContextAttributesA(hash cb) status %s [0x%08"PRIX32"]",
GetSecurityStatusString(status), status);
}
status = nla->table->SetContextAttributes(&nla->context, SECPKG_ATTR_AUTH_NTLM_HASH_CB_DATA, peer, 0);
status = nla->table->SetContextAttributes(&nla->context, SECPKG_ATTR_AUTH_NTLM_HASH_CB_DATA, peer,
0);
if (status != SEC_E_OK)
{
WLog_ERR(TAG, "SetContextAttributesA(hash cb data) status %s [0x%08"PRIX32"]", GetSecurityStatusString(status), status);
WLog_ERR(TAG, "SetContextAttributesA(hash cb data) status %s [0x%08"PRIX32"]",
GetSecurityStatusString(status), status);
}
}
else if (nla->SamFile)
{
nla->table->SetContextAttributes(&nla->context, SECPKG_ATTR_AUTH_NTLM_SAM_FILE, nla->SamFile,
strlen(nla->SamFile) + 1);
strlen(nla->SamFile) + 1);
}
if (nla->table->CompleteAuthToken)
@ -781,7 +831,7 @@ static int nla_server_authenticate(rdpNla* nla)
nla->havePubKeyAuth = TRUE;
nla->status = nla->table->QueryContextAttributes(&nla->context, SECPKG_ATTR_SIZES,
&nla->ContextSizes);
&nla->ContextSizes);
if (nla->status != SEC_E_OK)
{
@ -815,21 +865,21 @@ static int nla_server_authenticate(rdpNla* nla)
*/
switch (GetLastError())
{
case ERROR_PASSWORD_MUST_CHANGE:
nla->errorCode = STATUS_PASSWORD_MUST_CHANGE;
break;
case ERROR_PASSWORD_MUST_CHANGE:
nla->errorCode = STATUS_PASSWORD_MUST_CHANGE;
break;
case ERROR_PASSWORD_EXPIRED:
nla->errorCode = STATUS_PASSWORD_EXPIRED;
break;
case ERROR_PASSWORD_EXPIRED:
nla->errorCode = STATUS_PASSWORD_EXPIRED;
break;
case ERROR_ACCOUNT_DISABLED:
nla->errorCode = STATUS_ACCOUNT_DISABLED;
break;
case ERROR_ACCOUNT_DISABLED:
nla->errorCode = STATUS_ACCOUNT_DISABLED;
break;
default:
nla->errorCode = NTSTATUS_FROM_WIN32(GetLastError());
break;
default:
nla->errorCode = NTSTATUS_FROM_WIN32(GetLastError());
break;
}
WLog_ERR(TAG, "AcceptSecurityContext status %s [0x%08"PRIX32"]",
@ -962,18 +1012,29 @@ SECURITY_STATUS nla_encrypt_public_key_echo(rdpNla* nla)
int public_key_length;
public_key_length = nla->PublicKey.cbBuffer;
if (!sspi_SecBufferAlloc(&nla->pubKeyAuth, nla->ContextSizes.cbSecurityTrailer + public_key_length))
if (!sspi_SecBufferAlloc(&nla->pubKeyAuth, public_key_length + nla->ContextSizes.cbSecurityTrailer))
return SEC_E_INSUFFICIENT_MEMORY;
Buffers[0].BufferType = SECBUFFER_TOKEN; /* Signature */
Buffers[0].cbBuffer = nla->ContextSizes.cbSecurityTrailer;
Buffers[0].pvBuffer = nla->pubKeyAuth.pvBuffer;
Buffers[1].BufferType = SECBUFFER_DATA; /* TLS Public Key */
Buffers[1].cbBuffer = public_key_length;
Buffers[1].pvBuffer = ((BYTE*) nla->pubKeyAuth.pvBuffer) + nla->ContextSizes.cbSecurityTrailer;
CopyMemory(Buffers[1].pvBuffer, nla->PublicKey.pvBuffer, Buffers[1].cbBuffer);
if (strcmp(nla->packageName, KERBEROS_SSP_NAME) == 0)
{
Buffers[0].BufferType = SECBUFFER_DATA; /* TLS Public Key */
Buffers[0].cbBuffer = public_key_length;
Buffers[0].pvBuffer = nla->pubKeyAuth.pvBuffer;
CopyMemory(Buffers[0].pvBuffer, nla->PublicKey.pvBuffer, Buffers[0].cbBuffer);
}
else if ((strcmp(nla->packageName, NEGO_SSP_NAME) != 0) ||
(strcmp(nla->packageName, NTLM_SSP_NAME) != 0))
{
Buffers[0].BufferType = SECBUFFER_TOKEN; /* Signature */
Buffers[0].cbBuffer = nla->ContextSizes.cbSecurityTrailer;
Buffers[0].pvBuffer = nla->pubKeyAuth.pvBuffer;
Buffers[1].BufferType = SECBUFFER_DATA; /* TLS Public Key */
Buffers[1].cbBuffer = public_key_length;
Buffers[1].pvBuffer = ((BYTE*) nla->pubKeyAuth.pvBuffer) + nla->ContextSizes.cbSecurityTrailer;
CopyMemory(Buffers[1].pvBuffer, nla->PublicKey.pvBuffer, Buffers[1].cbBuffer);
}
if (nla->server)
if ((strcmp(nla->packageName, KERBEROS_SSP_NAME) != 0) && nla->server)
{
/* server echos the public key +1 */
ap_integer_increment_le((BYTE*) Buffers[1].pvBuffer, Buffers[1].cbBuffer);
@ -991,14 +1052,6 @@ SECURITY_STATUS nla_encrypt_public_key_echo(rdpNla* nla)
return status;
}
if (Buffers[0].cbBuffer < nla->ContextSizes.cbSecurityTrailer)
{
/* EncryptMessage may not use all the signature space, so we need to shrink the excess */
MoveMemory(((BYTE*)nla->pubKeyAuth.pvBuffer) + Buffers[0].cbBuffer, Buffers[1].pvBuffer,
Buffers[1].cbBuffer);
nla->pubKeyAuth.cbBuffer = Buffers[0].cbBuffer + Buffers[1].cbBuffer;
}
return status;
}
@ -1022,23 +1075,43 @@ SECURITY_STATUS nla_decrypt_public_key_echo(rdpNla* nla)
return SEC_E_INVALID_TOKEN;
}
if ((nla->PublicKey.cbBuffer + nla->ContextSizes.cbSecurityTrailer) != nla->pubKeyAuth.cbBuffer)
{
WLog_ERR(TAG, "unexpected pubKeyAuth buffer size: %"PRIu32"", (int) nla->pubKeyAuth.cbBuffer);
return SEC_E_INVALID_TOKEN;
}
length = nla->pubKeyAuth.cbBuffer;
buffer = (BYTE*) malloc(length);
if (!buffer)
return SEC_E_INSUFFICIENT_MEMORY;
CopyMemory(buffer, nla->pubKeyAuth.pvBuffer, length);
public_key_length = nla->PublicKey.cbBuffer;
Buffers[0].BufferType = SECBUFFER_TOKEN; /* Signature */
Buffers[0].cbBuffer = signature_length;
Buffers[0].pvBuffer = buffer;
Buffers[1].BufferType = SECBUFFER_DATA; /* Encrypted TLS Public Key */
Buffers[1].cbBuffer = length - signature_length;
Buffers[1].pvBuffer = buffer + signature_length;
Message.cBuffers = 2;
Message.ulVersion = SECBUFFER_VERSION;
Message.pBuffers = (PSecBuffer) &Buffers;
if (strcmp(nla->packageName, KERBEROS_SSP_NAME) == 0)
{
CopyMemory(buffer, nla->pubKeyAuth.pvBuffer, length);
Buffers[0].BufferType = SECBUFFER_DATA; /* Wrapped and encrypted TLS Public Key */
Buffers[0].cbBuffer = length;
Buffers[0].pvBuffer = buffer;
Message.cBuffers = 1;
Message.ulVersion = SECBUFFER_VERSION;
Message.pBuffers = (PSecBuffer) &Buffers;
}
else if ((strcmp(nla->packageName, NEGO_SSP_NAME) == 0) ||
(strcmp(nla->packageName, NTLM_SSP_NAME) == 0))
{
CopyMemory(buffer, nla->pubKeyAuth.pvBuffer, length);
public_key_length = nla->PublicKey.cbBuffer;
Buffers[0].BufferType = SECBUFFER_TOKEN; /* Signature */
Buffers[0].cbBuffer = signature_length;
Buffers[0].pvBuffer = buffer;
Buffers[1].BufferType = SECBUFFER_DATA; /* Encrypted TLS Public Key */
Buffers[1].cbBuffer = length - signature_length;
Buffers[1].pvBuffer = buffer + signature_length;
Message.cBuffers = 2;
Message.ulVersion = SECBUFFER_VERSION;
Message.pBuffers = (PSecBuffer) &Buffers;
}
status = nla->table->DecryptMessage(&nla->context, &Message, nla->recvSeqNum++, &pfQOP);
if (status != SEC_E_OK)
@ -1049,8 +1122,17 @@ SECURITY_STATUS nla_decrypt_public_key_echo(rdpNla* nla)
return status;
}
public_key1 = (BYTE*) nla->PublicKey.pvBuffer;
public_key2 = (BYTE*) Buffers[1].pvBuffer;
if (strcmp(nla->packageName, KERBEROS_SSP_NAME) == 0)
{
public_key1 = public_key2 = (BYTE*) nla->pubKeyAuth.pvBuffer ;
public_key_length = length;
}
else if ((strcmp(nla->packageName, NEGO_SSP_NAME) == 0) ||
(strcmp(nla->packageName, NTLM_SSP_NAME) == 0))
{
public_key1 = (BYTE*) nla->PublicKey.pvBuffer;
public_key2 = (BYTE*) Buffers[1].pvBuffer;
}
if (!nla->server)
{
@ -1087,6 +1169,15 @@ int nla_sizeof_ts_password_creds(rdpNla* nla)
return length;
}
static int nla_sizeof_ts_credentials(rdpNla* nla)
{
int size = 0;
size += ber_sizeof_integer(1);
size += ber_sizeof_contextual_tag(ber_sizeof_integer(1));
size += ber_sizeof_sequence_octet_string(ber_sizeof_sequence(nla_sizeof_ts_password_creds(nla)));
return size;
}
BOOL nla_read_ts_password_creds(rdpNla* nla, wStream* s)
{
int length;
@ -1207,15 +1298,6 @@ static int nla_write_ts_password_creds(rdpNla* nla, wStream* s)
return size;
}
static int nla_sizeof_ts_credentials(rdpNla* nla)
{
int size = 0;
size += ber_sizeof_integer(1);
size += ber_sizeof_contextual_tag(ber_sizeof_integer(1));
size += ber_sizeof_sequence_octet_string(ber_sizeof_sequence(nla_sizeof_ts_password_creds(nla)));
return size;
}
static BOOL nla_read_ts_credentials(rdpNla* nla, PSecBuffer ts_credentials)
{
wStream* s;
@ -1234,9 +1316,9 @@ static BOOL nla_read_ts_credentials(rdpNla* nla, PSecBuffer ts_credentials)
ret = ber_read_sequence_tag(s, &length) &&
/* [0] credType (INTEGER) */
ber_read_contextual_tag(s, 0, &length, TRUE) &&
ber_read_integer(s, NULL) &&
/* [1] credentials (OCTET STRING) */
ber_read_contextual_tag(s, 1, &length, TRUE) &&
ber_read_integer(s, NULL);
/* [1] credentials (OCTET STRING) */
ret += ber_read_contextual_tag(s, 1, &length, TRUE) &&
ber_read_octet_string_tag(s, &ts_password_creds_length) &&
nla_read_ts_password_creds(nla, s);
Stream_Free(s, FALSE);
@ -1276,6 +1358,7 @@ static BOOL nla_encode_ts_credentials(rdpNla* nla)
if (nla->identity)
{
/* TSPasswordCreds */
DomainLength = nla->identity->DomainLength;
UserLength = nla->identity->UserLength;
PasswordLength = nla->identity->PasswordLength;
@ -1283,6 +1366,7 @@ static BOOL nla_encode_ts_credentials(rdpNla* nla)
if (nla->settings->DisableCredentialsDelegation && nla->identity)
{
/* TSPasswordCreds */
nla->identity->DomainLength = 0;
nla->identity->UserLength = 0;
nla->identity->PasswordLength = 0;
@ -1309,6 +1393,7 @@ static BOOL nla_encode_ts_credentials(rdpNla* nla)
if (nla->settings->DisableCredentialsDelegation)
{
/* TSPasswordCreds */
nla->identity->DomainLength = DomainLength;
nla->identity->UserLength = UserLength;
nla->identity->PasswordLength = PasswordLength;
@ -1328,20 +1413,34 @@ static SECURITY_STATUS nla_encrypt_ts_credentials(rdpNla* nla)
return SEC_E_INSUFFICIENT_MEMORY;
if (!sspi_SecBufferAlloc(&nla->authInfo,
nla->ContextSizes.cbSecurityTrailer + nla->tsCredentials.cbBuffer))
nla->tsCredentials.cbBuffer + nla->ContextSizes.cbSecurityTrailer))
return SEC_E_INSUFFICIENT_MEMORY;
Buffers[0].BufferType = SECBUFFER_TOKEN; /* Signature */
Buffers[0].cbBuffer = nla->ContextSizes.cbSecurityTrailer;
Buffers[0].pvBuffer = nla->authInfo.pvBuffer;
ZeroMemory(Buffers[0].pvBuffer, Buffers[0].cbBuffer);
Buffers[1].BufferType = SECBUFFER_DATA; /* TSCredentials */
Buffers[1].cbBuffer = nla->tsCredentials.cbBuffer;
Buffers[1].pvBuffer = &((BYTE*) nla->authInfo.pvBuffer)[Buffers[0].cbBuffer];
CopyMemory(Buffers[1].pvBuffer, nla->tsCredentials.pvBuffer, Buffers[1].cbBuffer);
Message.cBuffers = 2;
Message.ulVersion = SECBUFFER_VERSION;
Message.pBuffers = (PSecBuffer) &Buffers;
if (strcmp(nla->packageName, KERBEROS_SSP_NAME) == 0)
{
Buffers[0].BufferType = SECBUFFER_DATA; /* TSCredentials */
Buffers[0].cbBuffer = nla->tsCredentials.cbBuffer;
Buffers[0].pvBuffer = nla->authInfo.pvBuffer;
CopyMemory(Buffers[0].pvBuffer, nla->tsCredentials.pvBuffer, Buffers[0].cbBuffer);
Message.cBuffers = 1;
Message.ulVersion = SECBUFFER_VERSION;
Message.pBuffers = (PSecBuffer) &Buffers;
}
else if ((strcmp(nla->packageName, NEGO_SSP_NAME) == 0) ||
(strcmp(nla->packageName, NTLM_SSP_NAME) == 0))
{
Buffers[0].BufferType = SECBUFFER_TOKEN; /* Signature */
Buffers[0].cbBuffer = nla->ContextSizes.cbSecurityTrailer;
Buffers[0].pvBuffer = nla->authInfo.pvBuffer;
MoveMemory(Buffers[0].pvBuffer, nla->authInfo.pvBuffer, Buffers[0].cbBuffer);
Buffers[1].BufferType = SECBUFFER_DATA; /* TSCredentials */
Buffers[1].cbBuffer = nla->tsCredentials.cbBuffer;
Buffers[1].pvBuffer = &((BYTE*) nla->authInfo.pvBuffer)[Buffers[0].cbBuffer];
CopyMemory(Buffers[1].pvBuffer, nla->tsCredentials.pvBuffer, Buffers[1].cbBuffer);
Message.cBuffers = 2;
Message.ulVersion = SECBUFFER_VERSION;
Message.pBuffers = (PSecBuffer) &Buffers;
}
status = nla->table->EncryptMessage(&nla->context, 0, &Message, nla->sendSeqNum++);
if (status != SEC_E_OK)
@ -1351,14 +1450,6 @@ static SECURITY_STATUS nla_encrypt_ts_credentials(rdpNla* nla)
return status;
}
if (Buffers[0].cbBuffer < nla->ContextSizes.cbSecurityTrailer)
{
/* EncryptMessage may not use all the signature space, so we need to shrink the excess */
MoveMemory(((BYTE*)nla->authInfo.pvBuffer) + Buffers[0].cbBuffer, Buffers[1].pvBuffer,
Buffers[1].cbBuffer);
nla->authInfo.cbBuffer = Buffers[0].cbBuffer + Buffers[1].cbBuffer;
}
return SEC_E_OK;
}
@ -1370,8 +1461,6 @@ static SECURITY_STATUS nla_decrypt_ts_credentials(rdpNla* nla)
SecBuffer Buffers[2];
SecBufferDesc Message;
SECURITY_STATUS status;
Buffers[0].BufferType = SECBUFFER_TOKEN; /* Signature */
Buffers[1].BufferType = SECBUFFER_DATA; /* TSCredentials */
if (nla->authInfo.cbBuffer < 1)
{
@ -1385,14 +1474,30 @@ static SECURITY_STATUS nla_decrypt_ts_credentials(rdpNla* nla)
if (!buffer)
return SEC_E_INSUFFICIENT_MEMORY;
CopyMemory(buffer, nla->authInfo.pvBuffer, length);
Buffers[0].cbBuffer = nla->ContextSizes.cbSecurityTrailer;
Buffers[0].pvBuffer = buffer;
Buffers[1].cbBuffer = length - nla->ContextSizes.cbSecurityTrailer;
Buffers[1].pvBuffer = &buffer[nla->ContextSizes.cbSecurityTrailer];
Message.cBuffers = 2;
Message.ulVersion = SECBUFFER_VERSION;
Message.pBuffers = (PSecBuffer) &Buffers;
if (strcmp(nla->packageName, KERBEROS_SSP_NAME) == 0)
{
CopyMemory(buffer, nla->authInfo.pvBuffer, length);
Buffers[0].BufferType = SECBUFFER_DATA; /* Wrapped and encrypted TSCredentials */
Buffers[0].cbBuffer = length;
Buffers[0].pvBuffer = buffer;
Message.cBuffers = 1;
Message.ulVersion = SECBUFFER_VERSION;
Message.pBuffers = (PSecBuffer) &Buffers;
}
else if ((strcmp(nla->packageName, NEGO_SSP_NAME) == 0) ||
(strcmp(nla->packageName, NTLM_SSP_NAME) == 0))
{
CopyMemory(buffer, nla->authInfo.pvBuffer, length);
Buffers[0].BufferType = SECBUFFER_TOKEN; /* Signature */
Buffers[0].cbBuffer = nla->ContextSizes.cbSecurityTrailer;
Buffers[0].pvBuffer = buffer;
Buffers[1].BufferType = SECBUFFER_DATA; /* TSCredentials */
Buffers[1].cbBuffer = length - nla->ContextSizes.cbSecurityTrailer;
Buffers[1].pvBuffer = &buffer[ Buffers[0].cbBuffer ];
Message.cBuffers = 2;
Message.ulVersion = SECBUFFER_VERSION;
Message.pBuffers = (PSecBuffer) &Buffers;
}
status = nla->table->DecryptMessage(&nla->context, &Message, nla->recvSeqNum++, &pfQOP);
if (status != SEC_E_OK)

View File

@ -1,6 +1,6 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Credential Security Support Provider (CredSSP)
* Network Level Authentication (NLA)
*
* Copyright 2010-2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
*
@ -60,6 +60,7 @@ struct rdp_nla
rdpSettings* settings;
rdpTransport* transport;
UINT32 cbMaxToken;
SEC_CHAR* packageName;
UINT32 version;
UINT32 errorCode;
ULONG fContextReq;

View File

@ -59,7 +59,7 @@
static void* transport_client_thread(void* arg);
#ifdef WITH_KRB5
#ifdef WITH_GSSAPI
#include <krb5.h>
#include <winpr/library.h>
@ -150,7 +150,7 @@ out:
krb5_free_context(context);
return ret;
}
#endif /* WITH_KRB5 */
#endif /* WITH_GSSAPI */
static void transport_ssl_cb(SSL* ssl, int where, int ret)
{
@ -174,7 +174,7 @@ static void transport_ssl_cb(SSL* ssl, int where, int ret)
if (transport->NlaMode)
{
UINT32 kret = 0;
#ifdef WITH_KRB5
#ifdef WITH_GSSAPI
if ((strlen(transport->settings->Domain) != 0) &&
(strncmp(transport->settings->Domain, ".", 1) != 0))
@ -184,7 +184,7 @@ static void transport_ssl_cb(SSL* ssl, int where, int ret)
transport->settings->Password);
}
else
#endif /* WITH_KRB5 */
#endif /* WITH_GSSAPI */
kret = FREERDP_ERROR_CONNECT_PASSWORD_CERTAINLY_EXPIRED;
if (!freerdp_get_last_error(transport->context))

View File

@ -92,8 +92,9 @@ typedef SecPkgInfoW* PSecPkgInfoW;
#define PSecPkgInfo PSecPkgInfoA
#endif
#define NTLMSP_NAME _T("NTLM")
#define NEGOSSP_NAME _T("Negotiate")
#define NTLMSSP_NAME _T("NTLM")
#define KERBEROS_SSP_NAME _T("Kerberos")
#define NEGOSSP_NAME _T("Negotiate")
#endif
@ -589,6 +590,7 @@ typedef SecPkgCredentials_NamesW* PSecPkgCredentials_NamesW;
typedef struct _SEC_WINNT_AUTH_IDENTITY_W
{
/* TSPasswordCreds */
UINT16* User;
UINT32 UserLength;
UINT16* Domain;
@ -600,6 +602,7 @@ typedef struct _SEC_WINNT_AUTH_IDENTITY_W
typedef struct _SEC_WINNT_AUTH_IDENTITY_A
{
/* TSPasswordCreds */
BYTE* User;
UINT32 UserLength;
BYTE* Domain;
@ -611,6 +614,7 @@ typedef struct _SEC_WINNT_AUTH_IDENTITY_A
struct _SEC_WINNT_AUTH_IDENTITY
{
/* TSPasswordCreds */
UINT16* User;
UINT32 UserLength;
UINT16* Domain;

View File

@ -27,6 +27,10 @@ set(${MODULE_PREFIX}_NTLM_SRCS
NTLM/ntlm.c
NTLM/ntlm.h)
set(${MODULE_PREFIX}_KERBEROS_SRCS
Kerberos/kerberos.c
Kerberos/kerberos.h)
set(${MODULE_PREFIX}_NEGOTIATE_SRCS
Negotiate/negotiate.c
Negotiate/negotiate.h)
@ -38,17 +42,20 @@ set(${MODULE_PREFIX}_SCHANNEL_SRCS
Schannel/schannel.h)
set(${MODULE_PREFIX}_CREDSSP_SRCS
CredSSP/credssp.c)
CredSSP/credssp.c
CredSSP/credssp.h)
set(${MODULE_PREFIX}_SRCS
${${MODULE_PREFIX}_CREDSSP_SRCS}
sspi_winpr.c
sspi_winpr.h
sspi_export.c
sspi_gss.c
sspi_gss.h
sspi.c
sspi.h)
winpr_module_add(${${MODULE_PREFIX}_NTLM_SRCS}
winpr_module_add(${${MODULE_PREFIX}_CREDSSP_SRCS}
${${MODULE_PREFIX}_NTLM_SRCS}
${${MODULE_PREFIX}_KERBEROS_SRCS}
${${MODULE_PREFIX}_NEGOTIATE_SRCS}
${${MODULE_PREFIX}_SCHANNEL_SRCS}
@ -64,6 +71,10 @@ if(MBEDTLS_FOUND)
winpr_library_add(${MBEDTLS_LIBRARIES})
endif()
if(GSS_FOUND)
winpr_library_add(${GSS_LIBRARIES})
endif()
if(WIN32)
winpr_library_add(ws2_32)
endif()

View File

@ -0,0 +1,734 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* Kerberos Auth Protocol
*
* Copyright 2015 ANSSI, Author Thomas Calderon
* Copyright 2017 Dorian Ducournau <dorian.ducournau@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <winpr/crt.h>
#include <winpr/sspi.h>
#include <winpr/print.h>
#include <winpr/sysinfo.h>
#include <winpr/registry.h>
#include "kerberos.h"
#include "../sspi.h"
#include "../../log.h"
#define TAG WINPR_TAG("sspi.Kerberos")
char* KRB_PACKAGE_NAME = "Kerberos";
static sspi_gss_OID_desc g_SSPI_GSS_C_SPNEGO_KRB5 = { 9, (void*) "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02" };
sspi_gss_OID SSPI_GSS_C_SPNEGO_KRB5 = &g_SSPI_GSS_C_SPNEGO_KRB5;
KRB_CONTEXT* kerberos_ContextNew()
{
KRB_CONTEXT* context;
context = (KRB_CONTEXT*) calloc(1, sizeof(KRB_CONTEXT));
if (!context)
return NULL;
context->minor_status = 0;
context->major_status = 0;
context->gss_ctx = SSPI_GSS_C_NO_CONTEXT;
context->cred = SSPI_GSS_C_NO_CREDENTIAL;
return context;
}
void kerberos_ContextFree(KRB_CONTEXT* context)
{
UINT32 minor_status;
if (!context)
return;
if (context->target_name)
{
sspi_gss_release_name(&minor_status, &context->target_name);
context->target_name = NULL;
}
if (context->gss_ctx)
{
sspi_gss_delete_sec_context(&minor_status, &context->gss_ctx, SSPI_GSS_C_NO_BUFFER);
context->gss_ctx = SSPI_GSS_C_NO_CONTEXT;
}
free(context);
}
SECURITY_STATUS SEC_ENTRY kerberos_AcquireCredentialsHandleW(SEC_WCHAR* pszPrincipal,
SEC_WCHAR* pszPackage,
ULONG fCredentialUse, void* pvLogonID, void* pAuthData,
SEC_GET_KEY_FN pGetKeyFn, void* pvGetKeyArgument,
PCredHandle phCredential, PTimeStamp ptsExpiry)
{
return SEC_E_OK;
}
SECURITY_STATUS SEC_ENTRY kerberos_AcquireCredentialsHandleA(SEC_CHAR* pszPrincipal,
SEC_CHAR* pszPackage,
ULONG fCredentialUse, void* pvLogonID, void* pAuthData,
SEC_GET_KEY_FN pGetKeyFn, void* pvGetKeyArgument,
PCredHandle phCredential, PTimeStamp ptsExpiry)
{
return SEC_E_OK;
}
SECURITY_STATUS SEC_ENTRY kerberos_FreeCredentialsHandle(PCredHandle phCredential)
{
SSPI_CREDENTIALS* credentials;
if (!phCredential)
return SEC_E_INVALID_HANDLE;
credentials = (SSPI_CREDENTIALS*) sspi_SecureHandleGetLowerPointer(phCredential);
if (!credentials)
return SEC_E_INVALID_HANDLE;
sspi_CredentialsFree(credentials);
return SEC_E_OK;
}
SECURITY_STATUS SEC_ENTRY kerberos_QueryCredentialsAttributesW(PCredHandle phCredential,
ULONG ulAttribute, void* pBuffer)
{
if (ulAttribute == SECPKG_CRED_ATTR_NAMES)
{
return SEC_E_OK;
}
return SEC_E_UNSUPPORTED_FUNCTION;
}
SECURITY_STATUS SEC_ENTRY kerberos_QueryCredentialsAttributesA(PCredHandle phCredential,
ULONG ulAttribute, void* pBuffer)
{
return kerberos_QueryCredentialsAttributesW(phCredential, ulAttribute, pBuffer);
}
SECURITY_STATUS SEC_ENTRY kerberos_InitializeSecurityContextW(PCredHandle phCredential,
PCtxtHandle phContext,
SEC_WCHAR* pszTargetName, ULONG fContextReq, ULONG Reserved1,
ULONG TargetDataRep, PSecBufferDesc pInput, ULONG Reserved2,
PCtxtHandle phNewContext, PSecBufferDesc pOutput,
ULONG* pfContextAttr, PTimeStamp ptsExpiry)
{
return SEC_E_UNSUPPORTED_FUNCTION;
}
int kerberos_SetContextServicePrincipalNameA(KRB_CONTEXT* context, SEC_CHAR* ServicePrincipalName)
{
char* p;
UINT32 major_status;
UINT32 minor_status;
char* gss_name = NULL;
sspi_gss_buffer_desc name_buffer;
if (!ServicePrincipalName)
{
context->target_name = NULL;
return 1;
}
/* GSSAPI expects a SPN of type <service>@FQDN, let's construct it */
gss_name = _strdup(ServicePrincipalName);
if (!gss_name)
return -1;
p = strchr(gss_name, '/');
if (p)
*p = '@';
name_buffer.value = gss_name;
name_buffer.length = strlen(gss_name) + 1;
major_status = sspi_gss_import_name(&minor_status, &name_buffer,
SSPI_GSS_C_NT_HOSTBASED_SERVICE, &(context->target_name));
free(gss_name);
if (SSPI_GSS_ERROR(major_status))
{
WLog_ERR(TAG, "error: gss_import_name failed");
return -1;
}
return 1;
}
#ifdef WITH_GSSAPI
krb5_error_code KRB5_CALLCONV
acquire_cred(krb5_context ctx, krb5_principal client, const char* password)
{
krb5_error_code ret;
krb5_creds creds;
krb5_deltat starttime = 0;
krb5_get_init_creds_opt* options = NULL;
krb5_ccache ccache;
krb5_init_creds_context init_ctx = NULL;
/* Get default ccache */
if ((ret = krb5_cc_default(ctx, &ccache)))
{
WLog_ERR(TAG, "error while getting default ccache");
goto cleanup;
}
if ((ret = krb5_cc_initialize(ctx, ccache, client)))
{
WLog_ERR(TAG, "error: could not initialize ccache");
goto cleanup;
}
memset(&creds, 0, sizeof(creds));
if ((ret = krb5_get_init_creds_opt_alloc(ctx, &options)))
{
WLog_ERR(TAG, "error while allocating options");
goto cleanup;
}
/* Set default options */
krb5_get_init_creds_opt_set_forwardable(options, 0);
krb5_get_init_creds_opt_set_proxiable(options, 0);
#ifdef WITH_GSSAPI_MIT
/* for MIT we specify ccache output using an option */
if ((ret = krb5_get_init_creds_opt_set_out_ccache(ctx, options, ccache)))
{
WLog_ERR(TAG, "error while setting ccache output");
goto cleanup;
}
#endif
if ((ret = krb5_init_creds_init(ctx, client, NULL, NULL, starttime, options, &init_ctx)))
{
WLog_ERR(TAG, "error krb5_init_creds_init failed");
goto cleanup;
}
if ((ret = krb5_init_creds_set_password(ctx, init_ctx, password)))
{
WLog_ERR(TAG, "error krb5_init_creds_set_password failed");
goto cleanup;
}
/* Get credentials */
if ((ret = krb5_init_creds_get(ctx, init_ctx)))
{
WLog_ERR(TAG, "error while getting credentials");
goto cleanup;
}
/* Retrieve credentials */
if ((ret = krb5_init_creds_get_creds(ctx, init_ctx, &creds)))
{
WLog_ERR(TAG, "error while retrieving credentials");
goto cleanup;
}
#ifdef WITH_GSSAPI_HEIMDAL
/* For Heimdal, we use this function to store credentials */
if ((ret = krb5_init_creds_store(ctx, init_ctx, ccache)))
{
WLog_ERR(TAG, "error while storing credentials");
goto cleanup;
}
#endif
cleanup:
krb5_free_cred_contents(ctx, &creds);
if (options)
krb5_get_init_creds_opt_free(ctx, options);
if (init_ctx)
krb5_init_creds_free(ctx, init_ctx);
if (ccache)
krb5_cc_close(ctx, ccache);
return ret;
}
int init_creds(LPCWSTR username, size_t username_len, LPCWSTR password, size_t password_len)
{
krb5_error_code ret = 0;
krb5_context ctx = NULL;
krb5_principal principal = NULL;
char* krb_name = NULL;
char* lusername = NULL;
char* lrealm = NULL;
char* lpassword = NULL;
size_t krb_name_len = 0;
size_t lrealm_len = 0;
size_t lusername_len = 0;
int status = 0;
status = ConvertFromUnicode(CP_UTF8, 0, username,
username_len, &lusername, 0, NULL, NULL);
if (status <= 0)
{
WLog_ERR(TAG, "Failed to convert username");
goto cleanup;
}
status = ConvertFromUnicode(CP_UTF8, 0, password,
password_len, &lpassword, 0, NULL, NULL);
if (status <= 0)
{
WLog_ERR(TAG, "Failed to convert password");
goto cleanup;
}
/* Could call krb5_init_secure_context, but it disallows user overrides */
ret = krb5_init_context(&ctx);
if (ret)
{
WLog_ERR(TAG, "error: while initializing Kerberos 5 library");
goto cleanup;
}
ret = krb5_get_default_realm(ctx, &lrealm);
if (ret)
{
WLog_WARN(TAG, "could not get Kerberos default realm");
goto cleanup;
}
lrealm_len = strlen(lrealm);
lusername_len = strlen(lusername);
krb_name_len = lusername_len + lrealm_len + 1; // +1 for '@'
krb_name = calloc(krb_name_len + 1, sizeof(char));
if (!krb_name)
{
WLog_ERR(TAG, "could not allocate memory for string rep of principal\n");
ret = -1;
goto cleanup;
}
/* Set buffer */
_snprintf(krb_name, krb_name_len + 1, "%s@%s", lusername, lrealm);
#ifdef WITH_DEBUG_NLA
WLog_DBG(TAG, "copied string is %s\n", krb_name);
#endif
ret = krb5_parse_name(ctx, krb_name, &principal);
if (ret)
{
WLog_ERR(TAG, "could not convert %s to principal", krb_name);
goto cleanup;
}
ret = acquire_cred(ctx, principal, lpassword);
if (ret)
{
WLog_ERR(TAG, "Kerberos credentials not found and could not be acquired");
goto cleanup;
}
cleanup:
free(lusername);
free(lpassword);
if (krb_name)
free(krb_name);
if (lrealm)
krb5_free_default_realm(ctx, lrealm);
if (principal)
krb5_free_principal(ctx, principal);
if (ctx)
krb5_free_context(ctx);
return ret;
}
#endif
SECURITY_STATUS SEC_ENTRY kerberos_InitializeSecurityContextA(PCredHandle phCredential,
PCtxtHandle phContext,
SEC_CHAR* pszTargetName, ULONG fContextReq, ULONG Reserved1,
ULONG TargetDataRep, PSecBufferDesc pInput, ULONG Reserved2,
PCtxtHandle phNewContext, PSecBufferDesc pOutput,
ULONG* pfContextAttr, PTimeStamp ptsExpiry)
{
KRB_CONTEXT* context;
SSPI_CREDENTIALS* credentials;
PSecBuffer input_buffer = NULL;
PSecBuffer output_buffer = NULL;
sspi_gss_buffer_desc input_tok;
sspi_gss_buffer_desc output_tok;
sspi_gss_OID actual_mech;
sspi_gss_OID desired_mech;
UINT32 actual_services;
input_tok.length = 0;
output_tok.length = 0;
desired_mech = SSPI_GSS_C_SPNEGO_KRB5;
context = (KRB_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext);
if (!context)
{
context = kerberos_ContextNew();
if (!context)
return SEC_E_INSUFFICIENT_MEMORY;
credentials = (SSPI_CREDENTIALS*) sspi_SecureHandleGetLowerPointer(phCredential);
context->credentials = credentials;
if (kerberos_SetContextServicePrincipalNameA(context, pszTargetName) < 0)
return SEC_E_INTERNAL_ERROR;
sspi_SecureHandleSetLowerPointer(phNewContext, context);
sspi_SecureHandleSetUpperPointer(phNewContext, (void*) KRB_PACKAGE_NAME);
}
if (!pInput)
{
#if defined(WITH_GSSAPI)
context->major_status = sspi_gss_init_sec_context(&(context->minor_status),
context->cred, &(context->gss_ctx), context->target_name,
desired_mech, SSPI_GSS_C_MUTUAL_FLAG | SSPI_GSS_C_DELEG_FLAG,
SSPI_GSS_C_INDEFINITE, SSPI_GSS_C_NO_CHANNEL_BINDINGS,
&input_tok, &actual_mech, &output_tok, &actual_services, &(context->actual_time));
if (SSPI_GSS_ERROR(context->major_status))
{
/* GSSAPI failed because we do not have credentials */
if (context->major_status & SSPI_GSS_S_NO_CRED)
{
/* Then let's try to acquire credentials using login and password,
* and only those two, means not with a smartcard.
* If we use smartcard-logon, the credentials have already
* been acquired by pkinit process. If not, returned error previously.
*/
if (init_creds(context->credentials->identity.User,
context->credentials->identity.UserLength,
context->credentials->identity.Password,
context->credentials->identity.PasswordLength))
return SEC_E_NO_CREDENTIALS;
else
WLog_INFO(TAG, "Authenticated to Kerberos v5 via login/password");
/* retry GSSAPI call */
context->major_status = sspi_gss_init_sec_context(&(context->minor_status),
context->cred, &(context->gss_ctx), context->target_name,
desired_mech, SSPI_GSS_C_MUTUAL_FLAG | SSPI_GSS_C_DELEG_FLAG,
SSPI_GSS_C_INDEFINITE, SSPI_GSS_C_NO_CHANNEL_BINDINGS,
&input_tok, &actual_mech, &output_tok, &actual_services, &(context->actual_time));
if (SSPI_GSS_ERROR(context->major_status))
{
/* We can't use Kerberos */
return SEC_E_INTERNAL_ERROR;
}
}
}
#endif
if (context->major_status & SSPI_GSS_S_CONTINUE_NEEDED)
{
if (output_tok.length != 0)
{
if (!pOutput)
return SEC_E_INVALID_TOKEN;
if (pOutput->cBuffers < 1)
return SEC_E_INVALID_TOKEN;
output_buffer = sspi_FindSecBuffer(pOutput, SECBUFFER_TOKEN);
if (!output_buffer)
return SEC_E_INVALID_TOKEN;
if (output_buffer->cbBuffer < 1)
return SEC_E_INVALID_TOKEN;
CopyMemory(output_buffer->pvBuffer, output_tok.value, output_tok.length);
output_buffer->cbBuffer = output_tok.length;
sspi_gss_release_buffer(&(context->minor_status), &output_tok);
return SEC_I_CONTINUE_NEEDED;
}
}
}
else
{
input_buffer = sspi_FindSecBuffer(pInput, SECBUFFER_TOKEN);
if (!input_buffer)
return SEC_E_INVALID_TOKEN;
if (input_buffer->cbBuffer < 1)
return SEC_E_INVALID_TOKEN;
input_tok.value = input_buffer->pvBuffer;
input_tok.length = input_buffer->cbBuffer;
context->major_status = sspi_gss_init_sec_context(&(context->minor_status),
context->cred, &(context->gss_ctx), context->target_name,
desired_mech, SSPI_GSS_C_MUTUAL_FLAG | SSPI_GSS_C_DELEG_FLAG,
SSPI_GSS_C_INDEFINITE, SSPI_GSS_C_NO_CHANNEL_BINDINGS,
&input_tok, &actual_mech, &output_tok, &actual_services, &(context->actual_time));
if (SSPI_GSS_ERROR(context->major_status))
return SEC_E_INTERNAL_ERROR;
if (output_tok.length == 0)
{
/* Free output_buffer to detect second call in NLA */
output_buffer = sspi_FindSecBuffer(pOutput, SECBUFFER_TOKEN);
sspi_SecBufferFree(output_buffer);
return SEC_E_OK;
}
else
{
return SEC_E_INTERNAL_ERROR;
}
}
return SEC_E_INTERNAL_ERROR;
}
SECURITY_STATUS SEC_ENTRY kerberos_DeleteSecurityContext(PCtxtHandle phContext)
{
KRB_CONTEXT* context;
context = (KRB_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext);
if (!context)
return SEC_E_INVALID_HANDLE;
kerberos_ContextFree(context);
return SEC_E_OK;
}
SECURITY_STATUS SEC_ENTRY kerberos_QueryContextAttributesW(PCtxtHandle phContext, ULONG ulAttribute,
void* pBuffer)
{
return SEC_E_OK;
}
SECURITY_STATUS SEC_ENTRY kerberos_QueryContextAttributesA(PCtxtHandle phContext, ULONG ulAttribute,
void* pBuffer)
{
if (!phContext)
return SEC_E_INVALID_HANDLE;
if (!pBuffer)
return SEC_E_INSUFFICIENT_MEMORY;
if (ulAttribute == SECPKG_ATTR_SIZES)
{
SecPkgContext_Sizes* ContextSizes = (SecPkgContext_Sizes*) pBuffer;
/* The MaxTokenSize by default is 12,000 bytes. This has been the default value
* since Windows 2000 SP2 and still remains in Windows 7 and Windows 2008 R2.
* For Windows Server 2012, the default value of the MaxTokenSize registry
* entry is 48,000 bytes.*/
ContextSizes->cbMaxToken = KERBEROS_SecPkgInfoA.cbMaxToken;
ContextSizes->cbMaxSignature = 0; /* means verify not supported */
ContextSizes->cbBlockSize = 0; /* padding not used */
ContextSizes->cbSecurityTrailer = 60; /* gss_wrap adds additional 60 bytes for encrypt message */
return SEC_E_OK;
}
return SEC_E_UNSUPPORTED_FUNCTION;
}
SECURITY_STATUS SEC_ENTRY kerberos_EncryptMessage(PCtxtHandle phContext, ULONG fQOP,
PSecBufferDesc pMessage, ULONG MessageSeqNo)
{
int index;
int conf_state;
UINT32 major_status;
UINT32 minor_status;
KRB_CONTEXT* context;
sspi_gss_buffer_desc input;
sspi_gss_buffer_desc output;
PSecBuffer data_buffer = NULL;
context = (KRB_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext);
if (!context)
return SEC_E_INVALID_HANDLE;
for (index = 0; index < (int) pMessage->cBuffers; index++)
{
if (pMessage->pBuffers[index].BufferType == SECBUFFER_DATA)
data_buffer = &pMessage->pBuffers[index];
}
if (!data_buffer)
return SEC_E_INVALID_TOKEN;
input.value = data_buffer->pvBuffer;
input.length = data_buffer->cbBuffer;
major_status = sspi_gss_wrap(&minor_status, context->gss_ctx, TRUE,
SSPI_GSS_C_QOP_DEFAULT, &input, &conf_state, &output);
if (SSPI_GSS_ERROR(major_status))
return SEC_E_INTERNAL_ERROR;
if (conf_state == 0)
{
WLog_ERR(TAG, "error: gss_wrap confidentiality was not applied");
sspi_gss_release_buffer(&minor_status, &output);
return SEC_E_INTERNAL_ERROR;
}
CopyMemory(data_buffer->pvBuffer, output.value, output.length);
sspi_gss_release_buffer(&minor_status, &output);
return SEC_E_OK;
}
SECURITY_STATUS SEC_ENTRY kerberos_DecryptMessage(PCtxtHandle phContext,
PSecBufferDesc pMessage, ULONG MessageSeqNo, ULONG* pfQOP)
{
int index;
int conf_state;
UINT32 major_status;
UINT32 minor_status;
KRB_CONTEXT* context;
sspi_gss_buffer_desc input_data;
sspi_gss_buffer_desc output;
PSecBuffer data_buffer_to_unwrap = NULL;
context = (KRB_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext);
if (!context)
return SEC_E_INVALID_HANDLE;
for (index = 0; index < (int) pMessage->cBuffers; index++)
{
if (pMessage->pBuffers[index].BufferType == SECBUFFER_DATA)
data_buffer_to_unwrap = &pMessage->pBuffers[index];
}
if (!data_buffer_to_unwrap)
return SEC_E_INVALID_TOKEN;
/* unwrap encrypted TLS key AND its signature */
input_data.value = data_buffer_to_unwrap->pvBuffer;
input_data.length = data_buffer_to_unwrap->cbBuffer;
major_status = sspi_gss_unwrap(&minor_status, context->gss_ctx, &input_data, &output, &conf_state,
NULL);
if (SSPI_GSS_ERROR(major_status))
return SEC_E_INTERNAL_ERROR;
if (conf_state == 0)
{
WLog_ERR(TAG, "error: gss_unwrap confidentiality was not applied");
sspi_gss_release_buffer(&minor_status, &output);
return SEC_E_INTERNAL_ERROR;
}
CopyMemory(data_buffer_to_unwrap->pvBuffer, output.value, output.length);
sspi_gss_release_buffer(&minor_status, &output);
return SEC_E_OK;
}
SECURITY_STATUS SEC_ENTRY kerberos_MakeSignature(PCtxtHandle phContext,
ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo)
{
return SEC_E_OK;
}
SECURITY_STATUS SEC_ENTRY kerberos_VerifySignature(PCtxtHandle phContext,
PSecBufferDesc pMessage, ULONG MessageSeqNo, ULONG* pfQOP)
{
return SEC_E_OK;
}
const SecurityFunctionTableA KERBEROS_SecurityFunctionTableA =
{
1, /* dwVersion */
NULL, /* EnumerateSecurityPackages */
kerberos_QueryCredentialsAttributesA, /* QueryCredentialsAttributes */
kerberos_AcquireCredentialsHandleA, /* AcquireCredentialsHandle */
kerberos_FreeCredentialsHandle, /* FreeCredentialsHandle */
NULL, /* Reserved2 */
kerberos_InitializeSecurityContextA, /* InitializeSecurityContext */
NULL, /* AcceptSecurityContext */
NULL, /* CompleteAuthToken */
kerberos_DeleteSecurityContext, /* DeleteSecurityContext */
NULL, /* ApplyControlToken */
kerberos_QueryContextAttributesA, /* QueryContextAttributes */
NULL, /* ImpersonateSecurityContext */
NULL, /* RevertSecurityContext */
kerberos_MakeSignature, /* MakeSignature */
kerberos_VerifySignature, /* VerifySignature */
NULL, /* FreeContextBuffer */
NULL, /* QuerySecurityPackageInfo */
NULL, /* Reserved3 */
NULL, /* Reserved4 */
NULL, /* ExportSecurityContext */
NULL, /* ImportSecurityContext */
NULL, /* AddCredentials */
NULL, /* Reserved8 */
NULL, /* QuerySecurityContextToken */
kerberos_EncryptMessage, /* EncryptMessage */
kerberos_DecryptMessage, /* DecryptMessage */
NULL, /* SetContextAttributes */
};
const SecurityFunctionTableW KERBEROS_SecurityFunctionTableW =
{
1, /* dwVersion */
NULL, /* EnumerateSecurityPackages */
kerberos_QueryCredentialsAttributesW, /* QueryCredentialsAttributes */
kerberos_AcquireCredentialsHandleW, /* AcquireCredentialsHandle */
kerberos_FreeCredentialsHandle, /* FreeCredentialsHandle */
NULL, /* Reserved2 */
kerberos_InitializeSecurityContextW, /* InitializeSecurityContext */
NULL, /* AcceptSecurityContext */
NULL, /* CompleteAuthToken */
kerberos_DeleteSecurityContext, /* DeleteSecurityContext */
NULL, /* ApplyControlToken */
kerberos_QueryContextAttributesW, /* QueryContextAttributes */
NULL, /* ImpersonateSecurityContext */
NULL, /* RevertSecurityContext */
kerberos_MakeSignature, /* MakeSignature */
kerberos_VerifySignature, /* VerifySignature */
NULL, /* FreeContextBuffer */
NULL, /* QuerySecurityPackageInfo */
NULL, /* Reserved3 */
NULL, /* Reserved4 */
NULL, /* ExportSecurityContext */
NULL, /* ImportSecurityContext */
NULL, /* AddCredentials */
NULL, /* Reserved8 */
NULL, /* QuerySecurityContextToken */
kerberos_EncryptMessage, /* EncryptMessage */
kerberos_DecryptMessage, /* DecryptMessage */
NULL, /* SetContextAttributes */
};

View File

@ -0,0 +1,83 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* Kerberos Auth Protocol
*
* Copyright 2015 ANSSI, Author Thomas Calderon
* Copyright 2017 Dorian Ducournau <dorian.ducournau@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FREERDP_SSPI_KERBEROS_PRIVATE_H
#define FREERDP_SSPI_KERBEROS_PRIVATE_H
#include <winpr/sspi.h>
#include <winpr/windows.h>
#include "../sspi.h"
#include "../../log.h"
#ifdef WITH_GSSAPI
#include <krb5.h>
#include <gssapi.h>
#endif
struct _KRB_CONTEXT
{
CtxtHandle context;
SSPI_CREDENTIALS* credentials;
SEC_WINNT_AUTH_IDENTITY identity;
/* GSSAPI */
UINT32 major_status;
UINT32 minor_status;
UINT32 actual_time;
sspi_gss_cred_id_t cred;
sspi_gss_ctx_id_t gss_ctx;
sspi_gss_name_t target_name;
};
typedef struct _KRB_CONTEXT KRB_CONTEXT;
const SecPkgInfoA KERBEROS_SecPkgInfoA =
{
0x000F3BBF, /* fCapabilities */
1, /* wVersion */
0x0010, /* wRPCID */
0x0000BB80, /* cbMaxToken : 48k bytes maximum for Windows Server 2012 */
"Kerberos", /* Name */
"Kerberos Security Package" /* Comment */
};
WCHAR KERBEROS_SecPkgInfoW_Name[] = { 'K', 'e', 'r', 'b', 'e', 'r', 'o', 's', '\0' };
WCHAR KERBEROS_SecPkgInfoW_Comment[] =
{
'K', 'e', 'r', 'b', 'e', 'r', 'o', 's', ' ',
'S', 'e', 'c', 'u', 'r', 'i', 't', 'y', ' ',
'P', 'a', 'c', 'k', 'a', 'g', 'e', '\0'
};
const SecPkgInfoW KERBEROS_SecPkgInfoW =
{
0x000F3BBF, /* fCapabilities */
1, /* wVersion */
0x0010, /* wRPCID */
0x0000BB80, /* cbMaxToken : 48k bytes maximum for Windows Server 2012 */
KERBEROS_SecPkgInfoW_Name, /* Name */
KERBEROS_SecPkgInfoW_Comment /* Comment */
};
void krb_ContextFree(KRB_CONTEXT* context);
#endif /* FREERDP_SSPI_KERBEROS_PRIVATE_H */

View File

@ -747,9 +747,10 @@ SECURITY_STATUS SEC_ENTRY ntlm_QueryContextAttributesW(PCtxtHandle phContext, UL
{
SecPkgContext_Sizes* ContextSizes = (SecPkgContext_Sizes*) pBuffer;
ContextSizes->cbMaxToken = 2010;
ContextSizes->cbMaxSignature = 16;
ContextSizes->cbBlockSize = 0;
ContextSizes->cbSecurityTrailer = 16;
ContextSizes->cbMaxSignature = 16; /* the size of expected signature is 16 bytes */
ContextSizes->cbBlockSize = 0; /* no padding */
ContextSizes->cbSecurityTrailer = 16; /* no security trailer appended in NTLM
contrary to Kerberos */
return SEC_E_OK;
}
else if (ulAttribute == SECPKG_ATTR_AUTH_IDENTITY)

View File

@ -3,6 +3,7 @@
* Negotiate Security Package
*
* Copyright 2011-2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
* Copyright 2017 Dorian Ducournau <dorian.ducournau@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -33,12 +34,37 @@
extern const SecurityFunctionTableA NTLM_SecurityFunctionTableA;
extern const SecurityFunctionTableW NTLM_SecurityFunctionTableW;
char* NEGOTIATE_PACKAGE_NAME = "Negotiate";
extern const SecurityFunctionTableA KERBEROS_SecurityFunctionTableA;
extern const SecurityFunctionTableW KERBEROS_SecurityFunctionTableW;
#ifdef WITH_GSSAPI
static BOOL ErrorInitContextKerberos = FALSE;
#else
static BOOL ErrorInitContextKerberos = TRUE;
#endif
void negotiate_SetSubPackage(NEGOTIATE_CONTEXT* context, const char* name)
{
if (strcmp(name, KERBEROS_SSP_NAME) == 0)
{
context->sspiA = (SecurityFunctionTableA*) &KERBEROS_SecurityFunctionTableA;
context->sspiW = (SecurityFunctionTableW*) &KERBEROS_SecurityFunctionTableW;
context->kerberos = TRUE;
}
else
{
context->sspiA = (SecurityFunctionTableA*) &NTLM_SecurityFunctionTableA;
context->sspiW = (SecurityFunctionTableW*) &NTLM_SecurityFunctionTableW;
context->kerberos = FALSE;
}
sspi_SecureHandleSetLowerPointer(&(context->SubContext), NULL);
sspi_SecureHandleSetUpperPointer(&(context->SubContext), NULL);
}
NEGOTIATE_CONTEXT* negotiate_ContextNew()
{
NEGOTIATE_CONTEXT* context;
context = (NEGOTIATE_CONTEXT*) calloc(1, sizeof(NEGOTIATE_CONTEXT));
if (!context)
@ -46,12 +72,8 @@ NEGOTIATE_CONTEXT* negotiate_ContextNew()
context->NegotiateFlags = 0;
context->state = NEGOTIATE_STATE_INITIAL;
SecInvalidateHandle(&(context->SubContext));
context->sspiA = (SecurityFunctionTableA*) &NTLM_SecurityFunctionTableA;
context->sspiW = (SecurityFunctionTableW*) &NTLM_SecurityFunctionTableW;
negotiate_SetSubPackage(context, KERBEROS_SSP_NAME);
return context;
}
@ -60,14 +82,14 @@ void negotiate_ContextFree(NEGOTIATE_CONTEXT* context)
free(context);
}
SECURITY_STATUS SEC_ENTRY negotiate_InitializeSecurityContextW(PCredHandle phCredential, PCtxtHandle phContext,
SEC_WCHAR* pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep,
PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext,
PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry)
SECURITY_STATUS SEC_ENTRY negotiate_InitializeSecurityContextW(PCredHandle phCredential,
PCtxtHandle phContext,
SEC_WCHAR* pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep,
PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext,
PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry)
{
SECURITY_STATUS status;
NEGOTIATE_CONTEXT* context;
context = (NEGOTIATE_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext);
if (!context)
@ -78,24 +100,54 @@ SECURITY_STATUS SEC_ENTRY negotiate_InitializeSecurityContextW(PCredHandle phCre
return SEC_E_INTERNAL_ERROR;
sspi_SecureHandleSetLowerPointer(phNewContext, context);
sspi_SecureHandleSetUpperPointer(phNewContext, (void*) NEGOTIATE_PACKAGE_NAME);
sspi_SecureHandleSetUpperPointer(phNewContext, (void*) NEGOSSP_NAME);
}
status = context->sspiW->InitializeSecurityContextW(phCredential, &(context->SubContext),
pszTargetName, fContextReq, Reserved1, TargetDataRep, pInput, Reserved2, &(context->SubContext),
pOutput, pfContextAttr, ptsExpiry);
/* if Kerberos has previously failed or WITH_GSSAPI is not defined, we use NTLM directly */
if (ErrorInitContextKerberos == FALSE)
{
if (!pInput)
{
negotiate_SetSubPackage(context, KERBEROS_SSP_NAME);
}
status = context->sspiW->InitializeSecurityContextW(phCredential, &(context->SubContext),
pszTargetName, fContextReq, Reserved1, TargetDataRep, pInput, Reserved2, &(context->SubContext),
pOutput, pfContextAttr, ptsExpiry);
if (status == SEC_E_NO_CREDENTIALS)
{
WLog_WARN(TAG, "No Kerberos credentials. Retry with NTLM");
ErrorInitContextKerberos = TRUE;
context->sspiA->DeleteSecurityContext(&(context->SubContext));
negotiate_ContextFree(context);
return status;
}
}
else
{
if (!pInput)
{
context->sspiA->DeleteSecurityContext(&(context->SubContext));
negotiate_SetSubPackage(context, NTLMSSP_NAME);
}
status = context->sspiW->InitializeSecurityContextW(phCredential, &(context->SubContext),
pszTargetName, fContextReq, Reserved1, TargetDataRep, pInput, Reserved2, &(context->SubContext),
pOutput, pfContextAttr, ptsExpiry);
}
return status;
}
SECURITY_STATUS SEC_ENTRY negotiate_InitializeSecurityContextA(PCredHandle phCredential, PCtxtHandle phContext,
SEC_CHAR* pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep,
PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext,
PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry)
SECURITY_STATUS SEC_ENTRY negotiate_InitializeSecurityContextA(PCredHandle phCredential,
PCtxtHandle phContext,
SEC_CHAR* pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep,
PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext,
PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry)
{
SECURITY_STATUS status;
NEGOTIATE_CONTEXT* context;
context = (NEGOTIATE_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext);
if (!context)
@ -106,23 +158,53 @@ SECURITY_STATUS SEC_ENTRY negotiate_InitializeSecurityContextA(PCredHandle phCre
return SEC_E_INTERNAL_ERROR;
sspi_SecureHandleSetLowerPointer(phNewContext, context);
sspi_SecureHandleSetUpperPointer(phNewContext, (void*) NEGOTIATE_PACKAGE_NAME);
sspi_SecureHandleSetUpperPointer(phNewContext, (void*) NEGOSSP_NAME);
}
status = context->sspiA->InitializeSecurityContextA(phCredential, &(context->SubContext),
pszTargetName, fContextReq, Reserved1, TargetDataRep, pInput, Reserved2, &(context->SubContext),
pOutput, pfContextAttr, ptsExpiry);
/* if Kerberos has previously failed or WITH_GSSAPI is not defined, we use NTLM directly */
if (ErrorInitContextKerberos == FALSE)
{
if (!pInput)
{
negotiate_SetSubPackage(context, KERBEROS_SSP_NAME);
}
status = context->sspiA->InitializeSecurityContextA(phCredential, &(context->SubContext),
pszTargetName, fContextReq, Reserved1, TargetDataRep, pInput, Reserved2, &(context->SubContext),
pOutput, pfContextAttr, ptsExpiry);
if (status == SEC_E_NO_CREDENTIALS)
{
WLog_WARN(TAG, "No Kerberos credentials. Retry with NTLM");
ErrorInitContextKerberos = TRUE;
context->sspiA->DeleteSecurityContext(&(context->SubContext));
negotiate_ContextFree(context);
return status;
}
}
else
{
if (!pInput)
{
context->sspiA->DeleteSecurityContext(&(context->SubContext));
negotiate_SetSubPackage(context, NTLMSSP_NAME);
}
status = context->sspiA->InitializeSecurityContextA(phCredential, &(context->SubContext),
pszTargetName, fContextReq, Reserved1, TargetDataRep, pInput, Reserved2, &(context->SubContext),
pOutput, pfContextAttr, ptsExpiry);
}
return status;
}
SECURITY_STATUS SEC_ENTRY negotiate_AcceptSecurityContext(PCredHandle phCredential, PCtxtHandle phContext,
PSecBufferDesc pInput, ULONG fContextReq, ULONG TargetDataRep, PCtxtHandle phNewContext,
PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsTimeStamp)
SECURITY_STATUS SEC_ENTRY negotiate_AcceptSecurityContext(PCredHandle phCredential,
PCtxtHandle phContext,
PSecBufferDesc pInput, ULONG fContextReq, ULONG TargetDataRep, PCtxtHandle phNewContext,
PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsTimeStamp)
{
SECURITY_STATUS status;
NEGOTIATE_CONTEXT* context;
context = (NEGOTIATE_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext);
if (!context)
@ -133,18 +215,20 @@ SECURITY_STATUS SEC_ENTRY negotiate_AcceptSecurityContext(PCredHandle phCredenti
return SEC_E_INTERNAL_ERROR;
sspi_SecureHandleSetLowerPointer(phNewContext, context);
sspi_SecureHandleSetUpperPointer(phNewContext, (void*) NEGOTIATE_PACKAGE_NAME);
sspi_SecureHandleSetUpperPointer(phNewContext, (void*) NEGOSSP_NAME);
}
negotiate_SetSubPackage(context, NTLMSSP_NAME); /* server-side Kerberos not yet implemented */
status = context->sspiA->AcceptSecurityContext(phCredential, &(context->SubContext),
pInput, fContextReq, TargetDataRep, &(context->SubContext),
pOutput, pfContextAttr, ptsTimeStamp);
pInput, fContextReq, TargetDataRep, &(context->SubContext),
pOutput, pfContextAttr, ptsTimeStamp);
if (status != SEC_E_OK)
{
WLog_WARN(TAG, "AcceptSecurityContext status %s [0x%08"PRIX32"]",
GetSecurityStatusString(status), status);
GetSecurityStatusString(status), status);
}
return status;
}
@ -152,7 +236,6 @@ SECURITY_STATUS SEC_ENTRY negotiate_CompleteAuthToken(PCtxtHandle phContext, PSe
{
NEGOTIATE_CONTEXT* context;
SECURITY_STATUS status = SEC_E_OK;
context = (NEGOTIATE_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext);
if (!context)
@ -168,7 +251,6 @@ SECURITY_STATUS SEC_ENTRY negotiate_DeleteSecurityContext(PCtxtHandle phContext)
{
NEGOTIATE_CONTEXT* context;
SECURITY_STATUS status = SEC_E_OK;
context = (NEGOTIATE_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext);
if (!context)
@ -178,7 +260,6 @@ SECURITY_STATUS SEC_ENTRY negotiate_DeleteSecurityContext(PCtxtHandle phContext)
status = context->sspiW->DeleteSecurityContext(&(context->SubContext));
negotiate_ContextFree(context);
return status;
}
@ -186,7 +267,6 @@ SECURITY_STATUS SEC_ENTRY negotiate_ImpersonateSecurityContext(PCtxtHandle phCon
{
NEGOTIATE_CONTEXT* context;
SECURITY_STATUS status = SEC_E_OK;
context = (NEGOTIATE_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext);
if (!phContext)
@ -202,7 +282,6 @@ SECURITY_STATUS SEC_ENTRY negotiate_RevertSecurityContext(PCtxtHandle phContext)
{
NEGOTIATE_CONTEXT* context;
SECURITY_STATUS status = SEC_E_OK;
context = (NEGOTIATE_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext);
if (!phContext)
@ -214,11 +293,11 @@ SECURITY_STATUS SEC_ENTRY negotiate_RevertSecurityContext(PCtxtHandle phContext)
return status;
}
SECURITY_STATUS SEC_ENTRY negotiate_QueryContextAttributesW(PCtxtHandle phContext, ULONG ulAttribute, void* pBuffer)
SECURITY_STATUS SEC_ENTRY negotiate_QueryContextAttributesW(PCtxtHandle phContext,
ULONG ulAttribute, void* pBuffer)
{
NEGOTIATE_CONTEXT* context;
SECURITY_STATUS status = SEC_E_OK;
context = (NEGOTIATE_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext);
if (!phContext)
@ -233,11 +312,11 @@ SECURITY_STATUS SEC_ENTRY negotiate_QueryContextAttributesW(PCtxtHandle phContex
return status;
}
SECURITY_STATUS SEC_ENTRY negotiate_QueryContextAttributesA(PCtxtHandle phContext, ULONG ulAttribute, void* pBuffer)
SECURITY_STATUS SEC_ENTRY negotiate_QueryContextAttributesA(PCtxtHandle phContext,
ULONG ulAttribute, void* pBuffer)
{
NEGOTIATE_CONTEXT* context;
SECURITY_STATUS status = SEC_E_OK;
context = (NEGOTIATE_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext);
if (!phContext)
@ -252,11 +331,11 @@ SECURITY_STATUS SEC_ENTRY negotiate_QueryContextAttributesA(PCtxtHandle phContex
return status;
}
SECURITY_STATUS SEC_ENTRY negotiate_SetContextAttributesW(PCtxtHandle phContext, ULONG ulAttribute, void* pBuffer, ULONG cbBuffer)
SECURITY_STATUS SEC_ENTRY negotiate_SetContextAttributesW(PCtxtHandle phContext, ULONG ulAttribute,
void* pBuffer, ULONG cbBuffer)
{
NEGOTIATE_CONTEXT* context;
SECURITY_STATUS status = SEC_E_OK;
context = (NEGOTIATE_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext);
if (!phContext)
@ -266,16 +345,17 @@ SECURITY_STATUS SEC_ENTRY negotiate_SetContextAttributesW(PCtxtHandle phContext,
return SEC_E_INSUFFICIENT_MEMORY;
if (context->sspiW->SetContextAttributesW)
status = context->sspiW->SetContextAttributesW(&(context->SubContext), ulAttribute, pBuffer, cbBuffer);
status = context->sspiW->SetContextAttributesW(&(context->SubContext), ulAttribute, pBuffer,
cbBuffer);
return status;
}
SECURITY_STATUS SEC_ENTRY negotiate_SetContextAttributesA(PCtxtHandle phContext, ULONG ulAttribute, void* pBuffer, ULONG cbBuffer)
SECURITY_STATUS SEC_ENTRY negotiate_SetContextAttributesA(PCtxtHandle phContext, ULONG ulAttribute,
void* pBuffer, ULONG cbBuffer)
{
NEGOTIATE_CONTEXT* context;
SECURITY_STATUS status = SEC_E_OK;
context = (NEGOTIATE_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext);
if (!phContext)
@ -285,21 +365,23 @@ SECURITY_STATUS SEC_ENTRY negotiate_SetContextAttributesA(PCtxtHandle phContext,
return SEC_E_INSUFFICIENT_MEMORY;
if (context->sspiA->SetContextAttributesA)
status = context->sspiA->SetContextAttributesA(&(context->SubContext), ulAttribute, pBuffer, cbBuffer);
status = context->sspiA->SetContextAttributesA(&(context->SubContext), ulAttribute, pBuffer,
cbBuffer);
return status;
}
SECURITY_STATUS SEC_ENTRY negotiate_AcquireCredentialsHandleW(SEC_WCHAR* pszPrincipal, SEC_WCHAR* pszPackage,
ULONG fCredentialUse, void* pvLogonID, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn,
void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
SECURITY_STATUS SEC_ENTRY negotiate_AcquireCredentialsHandleW(SEC_WCHAR* pszPrincipal,
SEC_WCHAR* pszPackage,
ULONG fCredentialUse, void* pvLogonID, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn,
void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
{
SSPI_CREDENTIALS* credentials;
SEC_WINNT_AUTH_IDENTITY* identity;
if ((fCredentialUse != SECPKG_CRED_OUTBOUND) &&
(fCredentialUse != SECPKG_CRED_INBOUND) &&
(fCredentialUse != SECPKG_CRED_BOTH))
(fCredentialUse != SECPKG_CRED_INBOUND) &&
(fCredentialUse != SECPKG_CRED_BOTH))
{
return SEC_E_INVALID_PARAMETER;
}
@ -312,28 +394,27 @@ SECURITY_STATUS SEC_ENTRY negotiate_AcquireCredentialsHandleW(SEC_WCHAR* pszPrin
credentials->fCredentialUse = fCredentialUse;
credentials->pGetKeyFn = pGetKeyFn;
credentials->pvGetKeyArgument = pvGetKeyArgument;
identity = (SEC_WINNT_AUTH_IDENTITY*) pAuthData;
if (identity)
sspi_CopyAuthIdentity(&(credentials->identity), identity);
sspi_SecureHandleSetLowerPointer(phCredential, (void*) credentials);
sspi_SecureHandleSetUpperPointer(phCredential, (void*) NEGOTIATE_PACKAGE_NAME);
sspi_SecureHandleSetUpperPointer(phCredential, (void*) NEGOSSP_NAME);
return SEC_E_OK;
}
SECURITY_STATUS SEC_ENTRY negotiate_AcquireCredentialsHandleA(SEC_CHAR* pszPrincipal, SEC_CHAR* pszPackage,
ULONG fCredentialUse, void* pvLogonID, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn,
void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
SECURITY_STATUS SEC_ENTRY negotiate_AcquireCredentialsHandleA(SEC_CHAR* pszPrincipal,
SEC_CHAR* pszPackage,
ULONG fCredentialUse, void* pvLogonID, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn,
void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
{
SSPI_CREDENTIALS* credentials;
SEC_WINNT_AUTH_IDENTITY* identity;
if ((fCredentialUse != SECPKG_CRED_OUTBOUND) &&
(fCredentialUse != SECPKG_CRED_INBOUND) &&
(fCredentialUse != SECPKG_CRED_BOTH))
(fCredentialUse != SECPKG_CRED_INBOUND) &&
(fCredentialUse != SECPKG_CRED_BOTH))
{
return SEC_E_INVALID_PARAMETER;
}
@ -346,24 +427,24 @@ SECURITY_STATUS SEC_ENTRY negotiate_AcquireCredentialsHandleA(SEC_CHAR* pszPrinc
credentials->fCredentialUse = fCredentialUse;
credentials->pGetKeyFn = pGetKeyFn;
credentials->pvGetKeyArgument = pvGetKeyArgument;
identity = (SEC_WINNT_AUTH_IDENTITY*) pAuthData;
if (identity)
sspi_CopyAuthIdentity(&(credentials->identity), identity);
sspi_SecureHandleSetLowerPointer(phCredential, (void*) credentials);
sspi_SecureHandleSetUpperPointer(phCredential, (void*) NEGOTIATE_PACKAGE_NAME);
sspi_SecureHandleSetUpperPointer(phCredential, (void*) NEGOSSP_NAME);
return SEC_E_OK;
}
SECURITY_STATUS SEC_ENTRY negotiate_QueryCredentialsAttributesW(PCredHandle phCredential, ULONG ulAttribute, void* pBuffer)
SECURITY_STATUS SEC_ENTRY negotiate_QueryCredentialsAttributesW(PCredHandle phCredential,
ULONG ulAttribute, void* pBuffer)
{
return SEC_E_UNSUPPORTED_FUNCTION;
}
SECURITY_STATUS SEC_ENTRY negotiate_QueryCredentialsAttributesA(PCredHandle phCredential, ULONG ulAttribute, void* pBuffer)
SECURITY_STATUS SEC_ENTRY negotiate_QueryCredentialsAttributesA(PCredHandle phCredential,
ULONG ulAttribute, void* pBuffer)
{
return SEC_E_UNSUPPORTED_FUNCTION;
}
@ -385,11 +466,11 @@ SECURITY_STATUS SEC_ENTRY negotiate_FreeCredentialsHandle(PCredHandle phCredenti
return SEC_E_OK;
}
SECURITY_STATUS SEC_ENTRY negotiate_EncryptMessage(PCtxtHandle phContext, ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo)
SECURITY_STATUS SEC_ENTRY negotiate_EncryptMessage(PCtxtHandle phContext, ULONG fQOP,
PSecBufferDesc pMessage, ULONG MessageSeqNo)
{
NEGOTIATE_CONTEXT* context;
SECURITY_STATUS status = SEC_E_UNSUPPORTED_FUNCTION;
context = (NEGOTIATE_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext);
if (context->sspiW->EncryptMessage)
@ -398,11 +479,11 @@ SECURITY_STATUS SEC_ENTRY negotiate_EncryptMessage(PCtxtHandle phContext, ULONG
return status;
}
SECURITY_STATUS SEC_ENTRY negotiate_DecryptMessage(PCtxtHandle phContext, PSecBufferDesc pMessage, ULONG MessageSeqNo, ULONG* pfQOP)
SECURITY_STATUS SEC_ENTRY negotiate_DecryptMessage(PCtxtHandle phContext, PSecBufferDesc pMessage,
ULONG MessageSeqNo, ULONG* pfQOP)
{
NEGOTIATE_CONTEXT* context;
SECURITY_STATUS status = SEC_E_UNSUPPORTED_FUNCTION;
context = (NEGOTIATE_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext);
if (context->sspiW->DecryptMessage)
@ -411,11 +492,11 @@ SECURITY_STATUS SEC_ENTRY negotiate_DecryptMessage(PCtxtHandle phContext, PSecBu
return status;
}
SECURITY_STATUS SEC_ENTRY negotiate_MakeSignature(PCtxtHandle phContext, ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo)
SECURITY_STATUS SEC_ENTRY negotiate_MakeSignature(PCtxtHandle phContext, ULONG fQOP,
PSecBufferDesc pMessage, ULONG MessageSeqNo)
{
NEGOTIATE_CONTEXT* context;
SECURITY_STATUS status = SEC_E_UNSUPPORTED_FUNCTION;
context = (NEGOTIATE_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext);
if (context->sspiW->MakeSignature)
@ -424,11 +505,11 @@ SECURITY_STATUS SEC_ENTRY negotiate_MakeSignature(PCtxtHandle phContext, ULONG f
return status;
}
SECURITY_STATUS SEC_ENTRY negotiate_VerifySignature(PCtxtHandle phContext, PSecBufferDesc pMessage, ULONG MessageSeqNo, ULONG* pfQOP)
SECURITY_STATUS SEC_ENTRY negotiate_VerifySignature(PCtxtHandle phContext, PSecBufferDesc pMessage,
ULONG MessageSeqNo, ULONG* pfQOP)
{
NEGOTIATE_CONTEXT* context;
SECURITY_STATUS status = SEC_E_UNSUPPORTED_FUNCTION;
context = (NEGOTIATE_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext);
if (context->sspiW->VerifySignature)
@ -511,13 +592,13 @@ const SecPkgInfoA NEGOTIATE_SecPkgInfoA =
"Microsoft Package Negotiator" /* Comment */
};
WCHAR NEGOTIATE_SecPkgInfoW_Name[] = { 'N','e','g','o','t','i','a','t','e','\0' };
WCHAR NEGOTIATE_SecPkgInfoW_Name[] = { 'N', 'e', 'g', 'o', 't', 'i', 'a', 't', 'e', '\0' };
WCHAR NEGOTIATE_SecPkgInfoW_Comment[] =
{
'M','i','c','r','o','s','o','f','t',' ',
'P','a','c','k','a','g','e',' ',
'N','e','g','o','t','i','a','t','o','r','\0'
'M', 'i', 'c', 'r', 'o', 's', 'o', 'f', 't', ' ',
'P', 'a', 'c', 'k', 'a', 'g', 'e', ' ',
'N', 'e', 'g', 'o', 't', 'i', 'a', 't', 'o', 'r', '\0'
};
const SecPkgInfoW NEGOTIATE_SecPkgInfoW =

View File

@ -44,6 +44,7 @@ struct _NEGOTIATE_CONTEXT
CtxtHandle SubContext;
BOOL kerberos;
SecurityFunctionTableA* sspiA;
SecurityFunctionTableW* sspiW;
};

View File

@ -85,6 +85,7 @@ enum SecurityFunctionTableIndex
BOOL IsSecurityStatusError(SECURITY_STATUS status);
#include "sspi_gss.h"
#include "sspi_winpr.h"
#endif /* WINPR_SSPI_PRIVATE_H */

View File

@ -0,0 +1,666 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Generic Security Service Application Program Interface (GSSAPI)
*
* Copyright 2015 ANSSI, Author Thomas Calderon
* Copyright 2015 Marc-Andre Moreau <marcandre.moreau@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <winpr/crt.h>
#include <winpr/library.h>
#include "sspi_gss.h"
#include "../../log.h"
#define TAG WINPR_TAG("sspi.gss")
int sspi_GssApiInit();
GSSAPI_FUNCTION_TABLE g_GssApi;
static BOOL g_Initialized = FALSE;
#define GSSAPI_STUB_CALL(_name, ...) \
if (!g_Initialized) \
sspi_GssApiInit(); \
if (!g_GssApi.gss_ ## _name) \
return 0; \
return g_GssApi.gss_ ## _name ( __VA_ARGS__ )
/**
* SSPI GSSAPI OIDs
*/
static sspi_gss_OID_desc g_SSPI_GSS_C_NT_USER_NAME = { 10, (void*) "\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x01" };
static sspi_gss_OID_desc g_SSPI_GSS_C_NT_MACHINE_UID_NAME = { 10, (void*) "\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x02" };
static sspi_gss_OID_desc g_SSPI_GSS_C_NT_STRING_UID_NAME = { 10, (void*) "\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x03" };
static sspi_gss_OID_desc g_SSPI_GSS_C_NT_HOSTBASED_SERVICE_X = { 6, (void*) "\x2b\x06\x01\x05\x06\x02" };
static sspi_gss_OID_desc g_SSPI_GSS_C_NT_HOSTBASED_SERVICE = { 10, (void*) "\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x04" };
static sspi_gss_OID_desc g_SSPI_GSS_C_NT_ANONYMOUS = { 6, (void*) "\x2b\x06\01\x05\x06\x03" };
static sspi_gss_OID_desc g_SSPI_GSS_C_NT_EXPORT_NAME = { 6, (void*) "\x2b\x06\x01\x05\x06\x04" };
sspi_gss_OID SSPI_GSS_C_NT_USER_NAME = &g_SSPI_GSS_C_NT_USER_NAME;
sspi_gss_OID SSPI_GSS_C_NT_MACHINE_UID_NAME = &g_SSPI_GSS_C_NT_MACHINE_UID_NAME;
sspi_gss_OID SSPI_GSS_C_NT_STRING_UID_NAME = &g_SSPI_GSS_C_NT_STRING_UID_NAME;
sspi_gss_OID SSPI_GSS_C_NT_HOSTBASED_SERVICE_X = &g_SSPI_GSS_C_NT_HOSTBASED_SERVICE_X;
sspi_gss_OID SSPI_GSS_C_NT_HOSTBASED_SERVICE = &g_SSPI_GSS_C_NT_HOSTBASED_SERVICE;
sspi_gss_OID SSPI_GSS_C_NT_ANONYMOUS = &g_SSPI_GSS_C_NT_ANONYMOUS;
sspi_gss_OID SSPI_GSS_C_NT_EXPORT_NAME = &g_SSPI_GSS_C_NT_EXPORT_NAME;
/**
* SSPI GSSAPI Wrapper Stubs
*/
UINT32 SSPI_GSSAPI sspi_gss_acquire_cred(
UINT32* minor_status,
sspi_gss_name_t desired_name,
UINT32 time_req,
sspi_gss_OID_set desired_mechs,
sspi_gss_cred_usage_t cred_usage,
sspi_gss_cred_id_t* output_cred_handle,
sspi_gss_OID_set* actual_mechs,
UINT32* time_rec)
{
GSSAPI_STUB_CALL(acquire_cred, minor_status, desired_name, time_req,
desired_mechs, cred_usage, output_cred_handle, actual_mechs, time_rec);
}
UINT32 SSPI_GSSAPI sspi_gss_release_cred(
UINT32* minor_status,
sspi_gss_cred_id_t* cred_handle)
{
GSSAPI_STUB_CALL(release_cred, minor_status, cred_handle);
}
UINT32 SSPI_GSSAPI sspi_gss_init_sec_context(
UINT32* minor_status,
sspi_gss_cred_id_t claimant_cred_handle,
sspi_gss_ctx_id_t* context_handle,
sspi_gss_name_t target_name,
sspi_gss_OID mech_type,
UINT32 req_flags,
UINT32 time_req,
sspi_gss_channel_bindings_t input_chan_bindings,
sspi_gss_buffer_t input_token,
sspi_gss_OID* actual_mech_type,
sspi_gss_buffer_t output_token,
UINT32* ret_flags,
UINT32* time_rec)
{
GSSAPI_STUB_CALL(init_sec_context, minor_status, claimant_cred_handle, context_handle,
target_name, mech_type, req_flags, time_req, input_chan_bindings,
input_token, actual_mech_type, output_token, ret_flags, time_rec);
}
UINT32 SSPI_GSSAPI sspi_gss_accept_sec_context(
UINT32* minor_status,
sspi_gss_ctx_id_t* context_handle,
sspi_gss_cred_id_t acceptor_cred_handle,
sspi_gss_buffer_t input_token_buffer,
sspi_gss_channel_bindings_t input_chan_bindings,
sspi_gss_name_t* src_name,
sspi_gss_OID* mech_type,
sspi_gss_buffer_t output_token,
UINT32* ret_flags,
UINT32* time_rec,
sspi_gss_cred_id_t* delegated_cred_handle)
{
GSSAPI_STUB_CALL(accept_sec_context, minor_status, context_handle, acceptor_cred_handle,
input_token_buffer, input_chan_bindings, src_name, mech_type, output_token,
ret_flags, time_rec, delegated_cred_handle);
}
UINT32 SSPI_GSSAPI sspi_gss_process_context_token(
UINT32* minor_status,
sspi_gss_ctx_id_t context_handle,
sspi_gss_buffer_t token_buffer)
{
GSSAPI_STUB_CALL(process_context_token, minor_status, context_handle, token_buffer);
}
UINT32 SSPI_GSSAPI sspi_gss_delete_sec_context(
UINT32* minor_status,
sspi_gss_ctx_id_t* context_handle,
sspi_gss_buffer_t output_token)
{
GSSAPI_STUB_CALL(delete_sec_context, minor_status, context_handle, output_token);
}
UINT32 SSPI_GSSAPI sspi_gss_context_time(
UINT32* minor_status,
sspi_gss_ctx_id_t context_handle,
UINT32* time_rec)
{
GSSAPI_STUB_CALL(context_time, minor_status, context_handle, time_rec);
}
UINT32 SSPI_GSSAPI sspi_gss_get_mic(
UINT32* minor_status,
sspi_gss_ctx_id_t context_handle,
sspi_gss_qop_t qop_req,
sspi_gss_buffer_t message_buffer,
sspi_gss_buffer_t message_token)
{
GSSAPI_STUB_CALL(get_mic, minor_status, context_handle, qop_req, message_buffer, message_token);
}
UINT32 SSPI_GSSAPI sspi_gss_verify_mic(
UINT32* minor_status,
sspi_gss_ctx_id_t context_handle,
sspi_gss_buffer_t message_buffer,
sspi_gss_buffer_t message_token,
sspi_gss_qop_t* qop_state)
{
GSSAPI_STUB_CALL(verify_mic, minor_status, context_handle, message_buffer, message_token,
qop_state);
}
UINT32 SSPI_GSSAPI sspi_gss_wrap(
UINT32* minor_status,
sspi_gss_ctx_id_t context_handle,
int conf_req_flag,
sspi_gss_qop_t qop_req,
sspi_gss_buffer_t input_message_buffer,
int* conf_state,
sspi_gss_buffer_t output_message_buffer)
{
GSSAPI_STUB_CALL(wrap, minor_status, context_handle, conf_req_flag,
qop_req, input_message_buffer, conf_state, output_message_buffer);
}
UINT32 SSPI_GSSAPI sspi_gss_unwrap(
UINT32* minor_status,
const sspi_gss_ctx_id_t context_handle,
const sspi_gss_buffer_t input_message_buffer,
sspi_gss_buffer_t output_message_buffer,
int* conf_state,
sspi_gss_qop_t* qop_state)
{
GSSAPI_STUB_CALL(unwrap, minor_status, context_handle, input_message_buffer,
output_message_buffer, conf_state, qop_state);
}
UINT32 SSPI_GSSAPI sspi_gss_display_status(
UINT32* minor_status,
UINT32 status_value,
int status_type,
sspi_gss_OID mech_type,
UINT32* message_context,
sspi_gss_buffer_t status_string)
{
GSSAPI_STUB_CALL(display_status, minor_status, status_value, status_type,
mech_type, message_context, status_string);
}
UINT32 SSPI_GSSAPI sspi_gss_indicate_mechs(
UINT32* minor_status,
sspi_gss_OID_set* mech_set)
{
GSSAPI_STUB_CALL(indicate_mechs, minor_status, mech_set);
}
UINT32 SSPI_GSSAPI sspi_gss_compare_name(
UINT32* minor_status,
sspi_gss_name_t name1,
sspi_gss_name_t name2,
int* name_equal)
{
GSSAPI_STUB_CALL(compare_name, minor_status, name1, name2, name_equal);
}
UINT32 SSPI_GSSAPI sspi_gss_display_name(
UINT32* minor_status,
sspi_gss_name_t input_name,
sspi_gss_buffer_t output_name_buffer,
sspi_gss_OID* output_name_type)
{
GSSAPI_STUB_CALL(display_name, minor_status, input_name, output_name_buffer, output_name_type);
}
UINT32 SSPI_GSSAPI sspi_gss_import_name(
UINT32* minor_status,
sspi_gss_buffer_t input_name_buffer,
sspi_gss_OID input_name_type,
sspi_gss_name_t* output_name)
{
GSSAPI_STUB_CALL(import_name, minor_status, input_name_buffer, input_name_type, output_name);
}
UINT32 SSPI_GSSAPI sspi_gss_release_name(
UINT32* minor_status,
sspi_gss_name_t* input_name)
{
GSSAPI_STUB_CALL(release_name, minor_status, input_name);
}
UINT32 SSPI_GSSAPI sspi_gss_release_buffer(
UINT32* minor_status,
sspi_gss_buffer_t buffer)
{
GSSAPI_STUB_CALL(release_buffer, minor_status, buffer);
}
UINT32 SSPI_GSSAPI sspi_gss_release_oid_set(
UINT32* minor_status,
sspi_gss_OID_set* set)
{
GSSAPI_STUB_CALL(release_oid_set, minor_status, set);
}
UINT32 SSPI_GSSAPI sspi_gss_inquire_cred(
UINT32* minor_status,
sspi_gss_cred_id_t cred_handle,
sspi_gss_name_t* name,
UINT32* lifetime,
sspi_gss_cred_usage_t* cred_usage,
sspi_gss_OID_set* mechanisms)
{
GSSAPI_STUB_CALL(inquire_cred, minor_status, cred_handle, name, lifetime, cred_usage, mechanisms);
}
UINT32 SSPI_GSSAPI sspi_gss_inquire_context(
UINT32* minor_status,
sspi_gss_ctx_id_t context_handle,
sspi_gss_name_t* src_name,
sspi_gss_name_t* targ_name,
UINT32* lifetime_rec,
sspi_gss_OID* mech_type,
UINT32* ctx_flags,
int* locally_initiated,
int* open)
{
GSSAPI_STUB_CALL(inquire_context, minor_status, context_handle, src_name, targ_name,
lifetime_rec, mech_type, ctx_flags, locally_initiated, open);
}
UINT32 SSPI_GSSAPI sspi_gss_wrap_size_limit(
UINT32* minor_status,
sspi_gss_ctx_id_t context_handle,
int conf_req_flag,
sspi_gss_qop_t qop_req,
UINT32 req_output_size,
UINT32* max_input_size)
{
GSSAPI_STUB_CALL(wrap_size_limit, minor_status, context_handle,
conf_req_flag, qop_req, req_output_size, max_input_size);
}
UINT32 SSPI_GSSAPI sspi_gss_import_name_object(
UINT32* minor_status,
void* input_name,
sspi_gss_OID input_name_type,
sspi_gss_name_t* output_name)
{
GSSAPI_STUB_CALL(import_name_object, minor_status, input_name, input_name_type, output_name);
}
UINT32 SSPI_GSSAPI sspi_gss_export_name_object(
UINT32* minor_status,
sspi_gss_name_t input_name,
sspi_gss_OID desired_name_type,
void** output_name)
{
GSSAPI_STUB_CALL(export_name_object, minor_status, input_name, desired_name_type, output_name);
}
UINT32 SSPI_GSSAPI sspi_gss_add_cred(
UINT32* minor_status,
sspi_gss_cred_id_t input_cred_handle,
sspi_gss_name_t desired_name,
sspi_gss_OID desired_mech,
sspi_gss_cred_usage_t cred_usage,
UINT32 initiator_time_req,
UINT32 acceptor_time_req,
sspi_gss_cred_id_t* output_cred_handle,
sspi_gss_OID_set* actual_mechs,
UINT32* initiator_time_rec,
UINT32* acceptor_time_rec)
{
GSSAPI_STUB_CALL(add_cred, minor_status, input_cred_handle, desired_name, desired_mech, cred_usage,
initiator_time_req, acceptor_time_req, output_cred_handle, actual_mechs, initiator_time_rec,
acceptor_time_rec);
}
UINT32 SSPI_GSSAPI sspi_gss_inquire_cred_by_mech(
UINT32* minor_status,
sspi_gss_cred_id_t cred_handle,
sspi_gss_OID mech_type,
sspi_gss_name_t* name,
UINT32* initiator_lifetime,
UINT32* acceptor_lifetime,
sspi_gss_cred_usage_t* cred_usage)
{
GSSAPI_STUB_CALL(inquire_cred_by_mech, minor_status, cred_handle, mech_type, name,
initiator_lifetime, acceptor_lifetime, cred_usage);
}
UINT32 SSPI_GSSAPI sspi_gss_export_sec_context(
UINT32* minor_status,
sspi_gss_ctx_id_t* context_handle,
sspi_gss_buffer_t interprocess_token)
{
GSSAPI_STUB_CALL(export_sec_context, minor_status, context_handle, interprocess_token);
}
UINT32 SSPI_GSSAPI sspi_gss_import_sec_context(
UINT32* minor_status,
sspi_gss_buffer_t interprocess_token,
sspi_gss_ctx_id_t* context_handle)
{
GSSAPI_STUB_CALL(import_sec_context, minor_status, interprocess_token, context_handle);
}
UINT32 SSPI_GSSAPI sspi_gss_release_oid(
UINT32* minor_status,
sspi_gss_OID* oid)
{
GSSAPI_STUB_CALL(release_oid, minor_status, oid);
}
UINT32 SSPI_GSSAPI sspi_gss_create_empty_oid_set(
UINT32* minor_status,
sspi_gss_OID_set* oid_set)
{
GSSAPI_STUB_CALL(create_empty_oid_set, minor_status, oid_set);
}
UINT32 SSPI_GSSAPI sspi_gss_add_oid_set_member(
UINT32* minor_status,
sspi_gss_OID member_oid,
sspi_gss_OID_set* oid_set)
{
GSSAPI_STUB_CALL(add_oid_set_member, minor_status, member_oid, oid_set);
}
UINT32 SSPI_GSSAPI sspi_gss_test_oid_set_member(
UINT32* minor_status,
sspi_gss_OID member,
sspi_gss_OID_set set,
int* present)
{
GSSAPI_STUB_CALL(test_oid_set_member, minor_status, member, set, present);
}
UINT32 SSPI_GSSAPI sspi_gss_str_to_oid(
UINT32* minor_status,
sspi_gss_buffer_t oid_str,
sspi_gss_OID* oid)
{
GSSAPI_STUB_CALL(str_to_oid, minor_status, oid_str, oid);
}
UINT32 SSPI_GSSAPI sspi_gss_oid_to_str(
UINT32* minor_status,
sspi_gss_OID oid,
sspi_gss_buffer_t oid_str)
{
GSSAPI_STUB_CALL(oid_to_str, minor_status, oid, oid_str);
}
UINT32 SSPI_GSSAPI sspi_gss_inquire_names_for_mech(
UINT32* minor_status,
sspi_gss_OID mechanism,
sspi_gss_OID_set* name_types)
{
GSSAPI_STUB_CALL(inquire_names_for_mech, minor_status, mechanism, name_types);
}
UINT32 SSPI_GSSAPI sspi_gss_inquire_mechs_for_name(
UINT32* minor_status,
const sspi_gss_name_t input_name,
sspi_gss_OID_set* mech_types)
{
GSSAPI_STUB_CALL(inquire_mechs_for_name, minor_status, input_name, mech_types);
}
UINT32 SSPI_GSSAPI sspi_gss_sign(
UINT32* minor_status,
sspi_gss_ctx_id_t context_handle,
int qop_req,
sspi_gss_buffer_t message_buffer,
sspi_gss_buffer_t message_token)
{
GSSAPI_STUB_CALL(sign, minor_status, context_handle, qop_req, message_buffer, message_token);
}
UINT32 SSPI_GSSAPI sspi_gss_verify(
UINT32* minor_status,
sspi_gss_ctx_id_t context_handle,
sspi_gss_buffer_t message_buffer,
sspi_gss_buffer_t token_buffer,
int* qop_state)
{
GSSAPI_STUB_CALL(verify, minor_status, context_handle, message_buffer, token_buffer, qop_state);
}
UINT32 SSPI_GSSAPI sspi_gss_seal(
UINT32* minor_status,
sspi_gss_ctx_id_t context_handle,
int conf_req_flag,
int qop_req,
sspi_gss_buffer_t input_message_buffer,
int* conf_state,
sspi_gss_buffer_t output_message_buffer)
{
GSSAPI_STUB_CALL(seal, minor_status, context_handle, conf_req_flag, qop_req,
input_message_buffer, conf_state, output_message_buffer);
}
UINT32 SSPI_GSSAPI sspi_gss_unseal(
UINT32* minor_status,
sspi_gss_ctx_id_t context_handle,
sspi_gss_buffer_t input_message_buffer,
sspi_gss_buffer_t output_message_buffer,
int* conf_state,
int* qop_state)
{
GSSAPI_STUB_CALL(unseal, minor_status, context_handle, input_message_buffer, output_message_buffer,
conf_state, qop_state);
}
UINT32 SSPI_GSSAPI sspi_gss_export_name(
UINT32* minor_status,
const sspi_gss_name_t input_name,
sspi_gss_buffer_t exported_name)
{
GSSAPI_STUB_CALL(export_name, minor_status, input_name, exported_name);
}
UINT32 SSPI_GSSAPI sspi_gss_duplicate_name(
UINT32* minor_status,
const sspi_gss_name_t input_name,
sspi_gss_name_t* dest_name)
{
GSSAPI_STUB_CALL(duplicate_name, minor_status, input_name, dest_name);
}
UINT32 SSPI_GSSAPI sspi_gss_canonicalize_name(
UINT32* minor_status,
const sspi_gss_name_t input_name,
const sspi_gss_OID mech_type,
sspi_gss_name_t* output_name)
{
GSSAPI_STUB_CALL(canonicalize_name, minor_status, input_name, mech_type, output_name);
}
UINT32 SSPI_GSSAPI sspi_gss_pseudo_random(
UINT32* minor_status,
sspi_gss_ctx_id_t context,
int prf_key,
const sspi_gss_buffer_t prf_in,
ssize_t desired_output_len,
sspi_gss_buffer_t prf_out)
{
GSSAPI_STUB_CALL(pseudo_random, minor_status, context, prf_key, prf_in, desired_output_len,
prf_out);
}
UINT32 SSPI_GSSAPI sspi_gss_store_cred(
UINT32* minor_status,
const sspi_gss_cred_id_t input_cred_handle,
sspi_gss_cred_usage_t input_usage,
const sspi_gss_OID desired_mech,
UINT32 overwrite_cred,
UINT32 default_cred,
sspi_gss_OID_set* elements_stored,
sspi_gss_cred_usage_t* cred_usage_stored)
{
GSSAPI_STUB_CALL(store_cred, minor_status, input_cred_handle, input_usage, desired_mech,
overwrite_cred, default_cred, elements_stored, cred_usage_stored);
}
UINT32 SSPI_GSSAPI sspi_gss_set_neg_mechs(
UINT32* minor_status,
sspi_gss_cred_id_t cred_handle,
const sspi_gss_OID_set mech_set)
{
GSSAPI_STUB_CALL(set_neg_mechs, minor_status, cred_handle, mech_set);
}
#ifdef WITH_GSSAPI
#include <gssapi/gssapi.h>
GSSAPI_FUNCTION_TABLE g_GssApiLink =
{
(fn_sspi_gss_acquire_cred) gss_acquire_cred, /* gss_acquire_cred */
(fn_sspi_gss_release_cred) gss_release_cred, /* gss_release_cred */
(fn_sspi_gss_init_sec_context) gss_init_sec_context, /* gss_init_sec_context */
(fn_sspi_gss_accept_sec_context) gss_accept_sec_context, /* gss_accept_sec_context */
(fn_sspi_gss_process_context_token) gss_process_context_token, /* gss_process_context_token */
(fn_sspi_gss_delete_sec_context) gss_delete_sec_context, /* gss_delete_sec_context */
(fn_sspi_gss_context_time) gss_context_time, /* gss_context_time */
(fn_sspi_gss_get_mic) gss_get_mic, /* gss_get_mic */
(fn_sspi_gss_verify_mic) gss_verify_mic, /* gss_verify_mic */
(fn_sspi_gss_wrap) gss_wrap, /* gss_wrap */
(fn_sspi_gss_unwrap) gss_unwrap, /* gss_unwrap */
(fn_sspi_gss_display_status) gss_display_status, /* gss_display_status */
(fn_sspi_gss_indicate_mechs) gss_indicate_mechs, /* gss_indicate_mechs */
(fn_sspi_gss_compare_name) gss_compare_name, /* gss_compare_name */
(fn_sspi_gss_display_name) gss_display_name, /* gss_display_name */
(fn_sspi_gss_import_name) gss_import_name, /* gss_import_name */
(fn_sspi_gss_release_name) gss_release_name, /* gss_release_name */
(fn_sspi_gss_release_buffer) gss_release_buffer, /* gss_release_buffer */
(fn_sspi_gss_release_oid_set) gss_release_oid_set, /* gss_release_oid_set */
(fn_sspi_gss_inquire_cred) gss_inquire_cred, /* gss_inquire_cred */
(fn_sspi_gss_inquire_context) gss_inquire_context, /* gss_inquire_context */
(fn_sspi_gss_wrap_size_limit) gss_wrap_size_limit, /* gss_wrap_size_limit */
#if 0
(fn_sspi_gss_import_name_object) gss_import_name_object, /* gss_import_name_object */
(fn_sspi_gss_export_name_object) gss_export_name_object, /* gss_export_name_object */
#else
(fn_sspi_gss_import_name_object) NULL, /* gss_import_name_object */
(fn_sspi_gss_export_name_object) NULL, /* gss_export_name_object */
#endif
(fn_sspi_gss_add_cred) gss_add_cred, /* gss_add_cred */
(fn_sspi_gss_inquire_cred_by_mech) gss_inquire_cred_by_mech, /* gss_inquire_cred_by_mech */
(fn_sspi_gss_export_sec_context) gss_export_sec_context, /* gss_export_sec_context */
(fn_sspi_gss_import_sec_context) gss_import_sec_context, /* gss_import_sec_context */
(fn_sspi_gss_release_oid) gss_release_oid, /* gss_release_oid */
(fn_sspi_gss_create_empty_oid_set) gss_create_empty_oid_set, /* gss_create_empty_oid_set */
(fn_sspi_gss_add_oid_set_member) gss_add_oid_set_member, /* gss_add_oid_set_member */
(fn_sspi_gss_test_oid_set_member) gss_test_oid_set_member, /* gss_test_oid_set_member */
#ifdef WITH_GSSAPI_MIT
(fn_sspi_gss_str_to_oid) gss_str_to_oid, /* gss_str_to_oid */
#else
(fn_sspi_gss_str_to_oid) NULL, /* gss_str_to_oid */
#endif
(fn_sspi_gss_oid_to_str) gss_oid_to_str, /* gss_oid_to_str */
(fn_sspi_gss_inquire_names_for_mech) gss_inquire_names_for_mech, /* gss_inquire_names_for_mech */
(fn_sspi_gss_inquire_mechs_for_name) gss_inquire_mechs_for_name, /* gss_inquire_mechs_for_name */
(fn_sspi_gss_sign) gss_sign, /* gss_sign */
(fn_sspi_gss_verify) gss_verify, /* gss_verify */
(fn_sspi_gss_seal) gss_seal, /* gss_seal */
(fn_sspi_gss_unseal) gss_unseal, /* gss_unseal */
(fn_sspi_gss_export_name) gss_export_name, /* gss_export_name */
(fn_sspi_gss_duplicate_name) gss_duplicate_name, /* gss_duplicate_name */
(fn_sspi_gss_canonicalize_name) gss_canonicalize_name, /* gss_canonicalize_name */
(fn_sspi_gss_pseudo_random) gss_pseudo_random, /* gss_pseudo_random */
(fn_sspi_gss_store_cred) gss_store_cred, /* gss_store_cred */
#ifdef WITH_GSSAPI_MIT
(fn_sspi_gss_set_neg_mechs) gss_set_neg_mechs, /* gss_set_neg_mechs */
#else
(fn_sspi_gss_set_neg_mechs) NULL, /* gss_set_neg_mechs */
#endif
};
#endif
GSSAPI_FUNCTION_TABLE g_GssApi =
{
NULL, /* gss_acquire_cred */
NULL, /* gss_release_cred */
NULL, /* gss_init_sec_context */
NULL, /* gss_accept_sec_context */
NULL, /* gss_process_context_token */
NULL, /* gss_delete_sec_context */
NULL, /* gss_context_time */
NULL, /* gss_get_mic */
NULL, /* gss_verify_mic */
NULL, /* gss_wrap */
NULL, /* gss_unwrap */
NULL, /* gss_display_status */
NULL, /* gss_indicate_mechs */
NULL, /* gss_compare_name */
NULL, /* gss_display_name */
NULL, /* gss_import_name */
NULL, /* gss_release_name */
NULL, /* gss_release_buffer */
NULL, /* gss_release_oid_set */
NULL, /* gss_inquire_cred */
NULL, /* gss_inquire_context */
NULL, /* gss_wrap_size_limit */
NULL, /* gss_import_name_object */
NULL, /* gss_export_name_object */
NULL, /* gss_add_cred */
NULL, /* gss_inquire_cred_by_mech */
NULL, /* gss_export_sec_context */
NULL, /* gss_import_sec_context */
NULL, /* gss_release_oid */
NULL, /* gss_create_empty_oid_set */
NULL, /* gss_add_oid_set_member */
NULL, /* gss_test_oid_set_member */
NULL, /* gss_str_to_oid */
NULL, /* gss_oid_to_str */
NULL, /* gss_inquire_names_for_mech */
NULL, /* gss_inquire_mechs_for_name */
NULL, /* gss_sign */
NULL, /* gss_verify */
NULL, /* gss_seal */
NULL, /* gss_unseal */
NULL, /* gss_export_name */
NULL, /* gss_duplicate_name */
NULL, /* gss_canonicalize_name */
NULL, /* gss_pseudo_random */
NULL, /* gss_store_cred */
NULL, /* gss_set_neg_mechs */
};
int sspi_GssApiInit()
{
if (g_Initialized)
return 1;
g_Initialized = TRUE;
#ifdef WITH_GSSAPI
CopyMemory(&g_GssApi, &g_GssApiLink, sizeof(GSSAPI_FUNCTION_TABLE));
return 1;
#else
return -1;
#endif
}

View File

@ -0,0 +1,883 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Generic Security Service Application Program Interface (GSSAPI)
*
* Copyright 2015 ANSSI, Author Thomas Calderon
* Copyright 2015 Marc-Andre Moreau <marcandre.moreau@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FREERDP_SSPI_GSS_PRIVATE_H
#define FREERDP_SSPI_GSS_PRIVATE_H
#include <winpr/crt.h>
#include <winpr/sspi.h>
/**
* The following are ABI-compatible, non-conflicting GSSAPI definitions
*
* http://tools.ietf.org/html/rfc2743
* http://tools.ietf.org/html/rfc2744
*/
#define SSPI_GSSAPI
#define SSPI_GSSOID
struct sspi_gss_name_struct;
typedef struct sspi_gss_name_struct* sspi_gss_name_t;
struct sspi_gss_cred_id_struct;
typedef struct sspi_gss_cred_id_struct* sspi_gss_cred_id_t;
struct sspi_gss_ctx_id_struct;
typedef struct sspi_gss_ctx_id_struct* sspi_gss_ctx_id_t;
typedef struct sspi_gss_OID_desc_struct
{
UINT32 length;
void* elements;
} sspi_gss_OID_desc, *sspi_gss_OID;
typedef struct sspi_gss_OID_set_desc_struct
{
size_t count;
sspi_gss_OID elements;
} sspi_gss_OID_set_desc, *sspi_gss_OID_set;
typedef struct sspi_gss_buffer_desc_struct
{
size_t length;
void* value;
} sspi_gss_buffer_desc, *sspi_gss_buffer_t;
typedef struct sspi_gss_channel_bindings_struct
{
UINT32 initiator_addrtype;
sspi_gss_buffer_desc initiator_address;
UINT32 acceptor_addrtype;
sspi_gss_buffer_desc acceptor_address;
sspi_gss_buffer_desc application_data;
}* sspi_gss_channel_bindings_t;
typedef UINT32 sspi_gss_qop_t;
typedef int sspi_gss_cred_usage_t;
#define SSPI_GSS_C_DELEG_FLAG 1
#define SSPI_GSS_C_MUTUAL_FLAG 2
#define SSPI_GSS_C_REPLAY_FLAG 4
#define SSPI_GSS_C_SEQUENCE_FLAG 8
#define SSPI_GSS_C_CONF_FLAG 16
#define SSPI_GSS_C_INTEG_FLAG 32
#define SSPI_GSS_C_ANON_FLAG 64
#define SSPI_GSS_C_PROT_READY_FLAG 128
#define SSPI_GSS_C_TRANS_FLAG 256
#define SSPI_GSS_C_DELEG_POLICY_FLAG 32768
#define SSPI_GSS_C_BOTH 0
#define SSPI_GSS_C_INITIATE 1
#define SSPI_GSS_C_ACCEPT 2
#define SSPI_GSS_C_GSS_CODE 1
#define SSPI_GSS_C_MECH_CODE 2
#define SSPI_GSS_C_AF_UNSPEC 0
#define SSPI_GSS_C_AF_LOCAL 1
#define SSPI_GSS_C_AF_INET 2
#define SSPI_GSS_C_AF_IMPLINK 3
#define SSPI_GSS_C_AF_PUP 4
#define SSPI_GSS_C_AF_CHAOS 5
#define SSPI_GSS_C_AF_NS 6
#define SSPI_GSS_C_AF_NBS 7
#define SSPI_GSS_C_AF_ECMA 8
#define SSPI_GSS_C_AF_DATAKIT 9
#define SSPI_GSS_C_AF_CCITT 10
#define SSPI_GSS_C_AF_SNA 11
#define SSPI_GSS_C_AF_DECnet 12
#define SSPI_GSS_C_AF_DLI 13
#define SSPI_GSS_C_AF_LAT 14
#define SSPI_GSS_C_AF_HYLINK 15
#define SSPI_GSS_C_AF_APPLETALK 16
#define SSPI_GSS_C_AF_BSC 17
#define SSPI_GSS_C_AF_DSS 18
#define SSPI_GSS_C_AF_OSI 19
#define SSPI_GSS_C_AF_NETBIOS 20
#define SSPI_GSS_C_AF_X25 21
#define SSPI_GSS_C_AF_NULLADDR 255
#define SSPI_GSS_C_NO_NAME ((sspi_gss_name_t) 0)
#define SSPI_GSS_C_NO_BUFFER ((sspi_gss_buffer_t) 0)
#define SSPI_GSS_C_NO_OID ((sspi_gss_OID) 0)
#define SSPI_GSS_C_NO_OID_SET ((sspi_gss_OID_set) 0)
#define SSPI_GSS_C_NO_CONTEXT ((sspi_gss_ctx_id_t) 0)
#define SSPI_GSS_C_NO_CREDENTIAL ((sspi_gss_cred_id_t) 0)
#define SSPI_GSS_C_NO_CHANNEL_BINDINGS ((sspi_gss_channel_bindings_t) 0)
#define SSPI_GSS_C_EMPTY_BUFFER {0, NULL}
#define SSPI_GSS_C_NULL_OID SSPI_GSS_C_NO_OID
#define SSPI_GSS_C_NULL_OID_SET SSPI_GSS_C_NO_OID_SET
#define SSPI_GSS_C_QOP_DEFAULT 0
#define SSPI_GSS_C_INDEFINITE ((UINT32) 0xFFFFFFFF)
#define SSPI_GSS_S_COMPLETE 0
#define SSPI_GSS_C_CALLING_ERROR_OFFSET 24
#define SSPI_GSS_C_ROUTINE_ERROR_OFFSET 16
#define SSPI_GSS_C_SUPPLEMENTARY_OFFSET 0
#define SSPI_GSS_C_CALLING_ERROR_MASK ((UINT32) 0377)
#define SSPI_GSS_C_ROUTINE_ERROR_MASK ((UINT32) 0377)
#define SSPI_GSS_C_SUPPLEMENTARY_MASK ((UINT32) 0177777)
#define SSPI_GSS_CALLING_ERROR(_x) \
((_x) & (SSPI_GSS_C_CALLING_ERROR_MASK << SSPI_GSS_C_CALLING_ERROR_OFFSET))
#define SSPI_GSS_ROUTINE_ERROR(_x) \
((_x) & (SSPI_GSS_C_ROUTINE_ERROR_MASK << SSPI_GSS_C_ROUTINE_ERROR_OFFSET))
#define SSPI_GSS_SUPPLEMENTARY_INFO(_x) \
((_x) & (SSPI_GSS_C_SUPPLEMENTARY_MASK << SSPI_GSS_C_SUPPLEMENTARY_OFFSET))
#define SSPI_GSS_ERROR(_x) \
((_x) & ((SSPI_GSS_C_CALLING_ERROR_MASK << SSPI_GSS_C_CALLING_ERROR_OFFSET) | \
(SSPI_GSS_C_ROUTINE_ERROR_MASK << SSPI_GSS_C_ROUTINE_ERROR_OFFSET)))
#define SSPI_GSS_S_CALL_INACCESSIBLE_READ (((UINT32) 1) << SSPI_GSS_C_CALLING_ERROR_OFFSET)
#define SSPI_GSS_S_CALL_INACCESSIBLE_WRITE (((UINT32) 2) << SSPI_GSS_C_CALLING_ERROR_OFFSET)
#define SSPI_GSS_S_CALL_BAD_STRUCTURE (((UINT32) 3) << SSPI_GSS_C_CALLING_ERROR_OFFSET)
#define SSPI_GSS_S_BAD_MECH (((UINT32) 1) << SSPI_GSS_C_ROUTINE_ERROR_OFFSET)
#define SSPI_GSS_S_BAD_NAME (((UINT32) 2) << SSPI_GSS_C_ROUTINE_ERROR_OFFSET)
#define SSPI_GSS_S_BAD_NAMETYPE (((UINT32) 3) << SSPI_GSS_C_ROUTINE_ERROR_OFFSET)
#define SSPI_GSS_S_BAD_BINDINGS (((UINT32) 4) << SSPI_GSS_C_ROUTINE_ERROR_OFFSET)
#define SSPI_GSS_S_BAD_STATUS (((UINT32) 5) << SSPI_GSS_C_ROUTINE_ERROR_OFFSET)
#define SSPI_GSS_S_BAD_SIG (((UINT32) 6) << SSPI_GSS_C_ROUTINE_ERROR_OFFSET)
#define SSPI_GSS_S_NO_CRED (((UINT32) 7) << SSPI_GSS_C_ROUTINE_ERROR_OFFSET)
#define SSPI_GSS_S_NO_CONTEXT (((UINT32) 8) << SSPI_GSS_C_ROUTINE_ERROR_OFFSET)
#define SSPI_GSS_S_DEFECTIVE_TOKEN (((UINT32) 9) << SSPI_GSS_C_ROUTINE_ERROR_OFFSET)
#define SSPI_GSS_S_DEFECTIVE_CREDENTIAL (((UINT32) 10) << SSPI_GSS_C_ROUTINE_ERROR_OFFSET)
#define SSPI_GSS_S_CREDENTIALS_EXPIRED (((UINT32) 11) << SSPI_GSS_C_ROUTINE_ERROR_OFFSET)
#define SSPI_GSS_S_CONTEXT_EXPIRED (((UINT32) 12) << SSPI_GSS_C_ROUTINE_ERROR_OFFSET)
#define SSPI_GSS_S_FAILURE (((UINT32) 13) << SSPI_GSS_C_ROUTINE_ERROR_OFFSET)
#define SSPI_GSS_S_BAD_QOP (((UINT32) 14) << SSPI_GSS_C_ROUTINE_ERROR_OFFSET)
#define SSPI_GSS_S_UNAUTHORIZED (((UINT32) 15) << SSPI_GSS_C_ROUTINE_ERROR_OFFSET)
#define SSPI_GSS_S_UNAVAILABLE (((UINT32) 16) << SSPI_GSS_C_ROUTINE_ERROR_OFFSET)
#define SSPI_GSS_S_DUPLICATE_ELEMENT (((UINT32) 17) << SSPI_GSS_C_ROUTINE_ERROR_OFFSET)
#define SSPI_GSS_S_NAME_NOT_MN (((UINT32) 18) << SSPI_GSS_C_ROUTINE_ERROR_OFFSET)
#define SSPI_GSS_S_BAD_MECH_ATTR (((UINT32) 19) << SSPI_GSS_C_ROUTINE_ERROR_OFFSET)
#define SSPI_GSS_S_CONTINUE_NEEDED (1 << (SSPI_GSS_C_SUPPLEMENTARY_OFFSET + 0))
#define SSPI_GSS_S_DUPLICATE_TOKEN (1 << (SSPI_GSS_C_SUPPLEMENTARY_OFFSET + 1))
#define SSPI_GSS_S_OLD_TOKEN (1 << (SSPI_GSS_C_SUPPLEMENTARY_OFFSET + 2))
#define SSPI_GSS_S_UNSEQ_TOKEN (1 << (SSPI_GSS_C_SUPPLEMENTARY_OFFSET + 3))
#define SSPI_GSS_S_GAP_TOKEN (1 << (SSPI_GSS_C_SUPPLEMENTARY_OFFSET + 4))
#define SSPI_GSS_C_PRF_KEY_FULL 0
#define SSPI_GSS_C_PRF_KEY_PARTIAL 1
#ifdef __cplusplus
extern "C" {
#endif
SSPI_GSSOID extern sspi_gss_OID SSPI_GSS_C_NT_USER_NAME;
SSPI_GSSOID extern sspi_gss_OID SSPI_GSS_C_NT_MACHINE_UID_NAME;
SSPI_GSSOID extern sspi_gss_OID SSPI_GSS_C_NT_STRING_UID_NAME;
SSPI_GSSOID extern sspi_gss_OID SSPI_GSS_C_NT_HOSTBASED_SERVICE_X;
SSPI_GSSOID extern sspi_gss_OID SSPI_GSS_C_NT_HOSTBASED_SERVICE;
SSPI_GSSOID extern sspi_gss_OID SSPI_GSS_C_NT_ANONYMOUS;
SSPI_GSSOID extern sspi_gss_OID SSPI_GSS_C_NT_EXPORT_NAME;
UINT32 SSPI_GSSAPI sspi_gss_acquire_cred(
UINT32* minor_status,
sspi_gss_name_t desired_name,
UINT32 time_req,
sspi_gss_OID_set desired_mechs,
sspi_gss_cred_usage_t cred_usage,
sspi_gss_cred_id_t* output_cred_handle,
sspi_gss_OID_set* actual_mechs,
UINT32* time_rec);
typedef UINT32(SSPI_GSSAPI* fn_sspi_gss_acquire_cred)(
UINT32* minor_status,
sspi_gss_name_t desired_name,
UINT32 time_req,
sspi_gss_OID_set desired_mechs,
sspi_gss_cred_usage_t cred_usage,
sspi_gss_cred_id_t* output_cred_handle,
sspi_gss_OID_set* actual_mechs,
UINT32* time_rec);
UINT32 SSPI_GSSAPI sspi_gss_release_cred(
UINT32* minor_status,
sspi_gss_cred_id_t* cred_handle);
typedef UINT32(SSPI_GSSAPI* fn_sspi_gss_release_cred)(
UINT32* minor_status,
sspi_gss_cred_id_t* cred_handle);
UINT32 SSPI_GSSAPI sspi_gss_init_sec_context(
UINT32* minor_status,
sspi_gss_cred_id_t claimant_cred_handle,
sspi_gss_ctx_id_t* context_handle,
sspi_gss_name_t target_name,
sspi_gss_OID mech_type,
UINT32 req_flags,
UINT32 time_req,
sspi_gss_channel_bindings_t input_chan_bindings,
sspi_gss_buffer_t input_token,
sspi_gss_OID* actual_mech_type,
sspi_gss_buffer_t output_token,
UINT32* ret_flags,
UINT32* time_rec);
typedef UINT32(SSPI_GSSAPI* fn_sspi_gss_init_sec_context)(
UINT32* minor_status,
sspi_gss_cred_id_t claimant_cred_handle,
sspi_gss_ctx_id_t* context_handle,
sspi_gss_name_t target_name,
sspi_gss_OID mech_type,
UINT32 req_flags,
UINT32 time_req,
sspi_gss_channel_bindings_t input_chan_bindings,
sspi_gss_buffer_t input_token,
sspi_gss_OID* actual_mech_type,
sspi_gss_buffer_t output_token,
UINT32* ret_flags,
UINT32* time_rec);
UINT32 SSPI_GSSAPI sspi_gss_accept_sec_context(
UINT32* minor_status,
sspi_gss_ctx_id_t* context_handle,
sspi_gss_cred_id_t acceptor_cred_handle,
sspi_gss_buffer_t input_token_buffer,
sspi_gss_channel_bindings_t input_chan_bindings,
sspi_gss_name_t* src_name,
sspi_gss_OID* mech_type,
sspi_gss_buffer_t output_token,
UINT32* ret_flags,
UINT32* time_rec,
sspi_gss_cred_id_t* delegated_cred_handle);
typedef UINT32(SSPI_GSSAPI* fn_sspi_gss_accept_sec_context)(
UINT32* minor_status,
sspi_gss_ctx_id_t* context_handle,
sspi_gss_cred_id_t acceptor_cred_handle,
sspi_gss_buffer_t input_token_buffer,
sspi_gss_channel_bindings_t input_chan_bindings,
sspi_gss_name_t* src_name,
sspi_gss_OID* mech_type,
sspi_gss_buffer_t output_token,
UINT32* ret_flags,
UINT32* time_rec,
sspi_gss_cred_id_t* delegated_cred_handle);
UINT32 SSPI_GSSAPI sspi_gss_process_context_token(
UINT32* minor_status,
sspi_gss_ctx_id_t context_handle,
sspi_gss_buffer_t token_buffer);
typedef UINT32(SSPI_GSSAPI* fn_sspi_gss_process_context_token)(
UINT32* minor_status,
sspi_gss_ctx_id_t context_handle,
sspi_gss_buffer_t token_buffer);
UINT32 SSPI_GSSAPI sspi_gss_delete_sec_context(
UINT32* minor_status,
sspi_gss_ctx_id_t* context_handle,
sspi_gss_buffer_t output_token);
typedef UINT32(SSPI_GSSAPI* fn_sspi_gss_delete_sec_context)(
UINT32* minor_status,
sspi_gss_ctx_id_t* context_handle,
sspi_gss_buffer_t output_token);
UINT32 SSPI_GSSAPI sspi_gss_context_time(
UINT32* minor_status,
sspi_gss_ctx_id_t context_handle,
UINT32* time_rec);
typedef UINT32(SSPI_GSSAPI* fn_sspi_gss_context_time)(
UINT32* minor_status,
sspi_gss_ctx_id_t context_handle,
UINT32* time_rec);
UINT32 SSPI_GSSAPI sspi_gss_get_mic(
UINT32* minor_status,
sspi_gss_ctx_id_t context_handle,
sspi_gss_qop_t qop_req,
sspi_gss_buffer_t message_buffer,
sspi_gss_buffer_t message_token);
typedef UINT32(SSPI_GSSAPI* fn_sspi_gss_get_mic)(
UINT32* minor_status,
sspi_gss_ctx_id_t context_handle,
sspi_gss_qop_t qop_req,
sspi_gss_buffer_t message_buffer,
sspi_gss_buffer_t message_token);
UINT32 SSPI_GSSAPI sspi_gss_verify_mic(
UINT32* minor_status,
sspi_gss_ctx_id_t context_handle,
sspi_gss_buffer_t message_buffer,
sspi_gss_buffer_t message_token,
sspi_gss_qop_t* qop_state);
typedef UINT32(SSPI_GSSAPI* fn_sspi_gss_verify_mic)(
UINT32* minor_status,
sspi_gss_ctx_id_t context_handle,
sspi_gss_buffer_t message_buffer,
sspi_gss_buffer_t message_token,
sspi_gss_qop_t* qop_state);
UINT32 SSPI_GSSAPI sspi_gss_wrap(
UINT32* minor_status,
sspi_gss_ctx_id_t context_handle,
int conf_req_flag,
sspi_gss_qop_t qop_req,
sspi_gss_buffer_t input_message_buffer,
int* conf_state,
sspi_gss_buffer_t output_message_buffer);
typedef UINT32(SSPI_GSSAPI* fn_sspi_gss_wrap)(
UINT32* minor_status,
sspi_gss_ctx_id_t context_handle,
int conf_req_flag,
sspi_gss_qop_t qop_req,
sspi_gss_buffer_t input_message_buffer,
int* conf_state,
sspi_gss_buffer_t output_message_buffer);
UINT32 SSPI_GSSAPI sspi_gss_unwrap(
UINT32* minor_status,
const sspi_gss_ctx_id_t context_handle,
const sspi_gss_buffer_t input_message_buffer,
sspi_gss_buffer_t output_message_buffer,
int* conf_state,
sspi_gss_qop_t* qop_state);
typedef UINT32(SSPI_GSSAPI* fn_sspi_gss_unwrap)(
UINT32* minor_status,
sspi_gss_ctx_id_t context_handle,
sspi_gss_buffer_t input_message_buffer,
sspi_gss_buffer_t output_message_buffer,
int* conf_state,
sspi_gss_qop_t* qop_state);
UINT32 SSPI_GSSAPI sspi_gss_display_status(
UINT32* minor_status,
UINT32 status_value,
int status_type,
sspi_gss_OID mech_type,
UINT32* message_context,
sspi_gss_buffer_t status_string);
typedef UINT32(SSPI_GSSAPI* fn_sspi_gss_display_status)(
UINT32* minor_status,
UINT32 status_value,
int status_type,
sspi_gss_OID mech_type,
UINT32* message_context,
sspi_gss_buffer_t status_string);
UINT32 SSPI_GSSAPI sspi_gss_indicate_mechs(
UINT32* minor_status,
sspi_gss_OID_set* mech_set);
typedef UINT32(SSPI_GSSAPI* fn_sspi_gss_indicate_mechs)(
UINT32* minor_status,
sspi_gss_OID_set* mech_set);
UINT32 SSPI_GSSAPI sspi_gss_compare_name(
UINT32* minor_status,
sspi_gss_name_t name1,
sspi_gss_name_t name2,
int* name_equal);
typedef UINT32(SSPI_GSSAPI* fn_sspi_gss_compare_name)(
UINT32* minor_status,
sspi_gss_name_t name1,
sspi_gss_name_t name2,
int* name_equal);
UINT32 SSPI_GSSAPI sspi_gss_display_name(
UINT32* minor_status,
sspi_gss_name_t input_name,
sspi_gss_buffer_t output_name_buffer,
sspi_gss_OID* output_name_type);
typedef UINT32(SSPI_GSSAPI* fn_sspi_gss_display_name)(
UINT32* minor_status,
sspi_gss_name_t input_name,
sspi_gss_buffer_t output_name_buffer,
sspi_gss_OID* output_name_type);
UINT32 SSPI_GSSAPI sspi_gss_import_name(
UINT32* minor_status,
sspi_gss_buffer_t input_name_buffer,
sspi_gss_OID input_name_type,
sspi_gss_name_t* output_name);
typedef UINT32(SSPI_GSSAPI* fn_sspi_gss_import_name)(
UINT32* minor_status,
sspi_gss_buffer_t input_name_buffer,
sspi_gss_OID input_name_type,
sspi_gss_name_t* output_name);
UINT32 SSPI_GSSAPI sspi_gss_release_name(
UINT32* minor_status,
sspi_gss_name_t* input_name);
typedef UINT32(SSPI_GSSAPI* fn_sspi_gss_release_name)(
UINT32* minor_status,
sspi_gss_name_t* input_name);
UINT32 SSPI_GSSAPI sspi_gss_release_buffer(
UINT32* minor_status,
sspi_gss_buffer_t buffer);
typedef UINT32(SSPI_GSSAPI* fn_sspi_gss_release_buffer)(
UINT32* minor_status,
sspi_gss_buffer_t buffer);
UINT32 SSPI_GSSAPI sspi_gss_release_oid_set(
UINT32* minor_status,
sspi_gss_OID_set* set);
typedef UINT32(SSPI_GSSAPI* fn_sspi_gss_release_oid_set)(
UINT32* minor_status,
sspi_gss_OID_set* set);
UINT32 SSPI_GSSAPI sspi_gss_inquire_cred(
UINT32* minor_status,
sspi_gss_cred_id_t cred_handle,
sspi_gss_name_t* name,
UINT32* lifetime,
sspi_gss_cred_usage_t* cred_usage,
sspi_gss_OID_set* mechanisms);
typedef UINT32(SSPI_GSSAPI* fn_sspi_gss_inquire_cred)(
UINT32* minor_status,
sspi_gss_cred_id_t cred_handle,
sspi_gss_name_t* name,
UINT32* lifetime,
sspi_gss_cred_usage_t* cred_usage,
sspi_gss_OID_set* mechanisms);
UINT32 SSPI_GSSAPI sspi_gss_inquire_context(
UINT32* minor_status,
sspi_gss_ctx_id_t context_handle,
sspi_gss_name_t* src_name,
sspi_gss_name_t* targ_name,
UINT32* lifetime_rec,
sspi_gss_OID* mech_type,
UINT32* ctx_flags,
int* locally_initiated,
int* open);
typedef UINT32(SSPI_GSSAPI* fn_sspi_gss_inquire_context)(
UINT32* minor_status,
sspi_gss_ctx_id_t context_handle,
sspi_gss_name_t* src_name,
sspi_gss_name_t* targ_name,
UINT32* lifetime_rec,
sspi_gss_OID* mech_type,
UINT32* ctx_flags,
int* locally_initiated,
int* open);
UINT32 SSPI_GSSAPI sspi_gss_wrap_size_limit(
UINT32* minor_status,
sspi_gss_ctx_id_t context_handle,
int conf_req_flag,
sspi_gss_qop_t qop_req,
UINT32 req_output_size,
UINT32* max_input_size);
typedef UINT32(SSPI_GSSAPI* fn_sspi_gss_wrap_size_limit)(
UINT32* minor_status,
sspi_gss_ctx_id_t context_handle,
int conf_req_flag,
sspi_gss_qop_t qop_req,
UINT32 req_output_size,
UINT32* max_input_size);
UINT32 SSPI_GSSAPI sspi_gss_import_name_object(
UINT32* minor_status,
void* input_name,
sspi_gss_OID input_name_type,
sspi_gss_name_t* output_name);
typedef UINT32(SSPI_GSSAPI* fn_sspi_gss_import_name_object)(
UINT32* minor_status,
void* input_name,
sspi_gss_OID input_name_type,
sspi_gss_name_t* output_name);
UINT32 SSPI_GSSAPI sspi_gss_export_name_object(
UINT32* minor_status,
sspi_gss_name_t input_name,
sspi_gss_OID desired_name_type,
void** output_name);
typedef UINT32(SSPI_GSSAPI* fn_sspi_gss_export_name_object)(
UINT32* minor_status,
sspi_gss_name_t input_name,
sspi_gss_OID desired_name_type,
void** output_name);
UINT32 SSPI_GSSAPI sspi_gss_add_cred(
UINT32* minor_status,
sspi_gss_cred_id_t input_cred_handle,
sspi_gss_name_t desired_name,
sspi_gss_OID desired_mech,
sspi_gss_cred_usage_t cred_usage,
UINT32 initiator_time_req,
UINT32 acceptor_time_req,
sspi_gss_cred_id_t* output_cred_handle,
sspi_gss_OID_set* actual_mechs,
UINT32* initiator_time_rec,
UINT32* acceptor_time_rec);
typedef UINT32(SSPI_GSSAPI* fn_sspi_gss_add_cred)(
UINT32* minor_status,
sspi_gss_cred_id_t input_cred_handle,
sspi_gss_name_t desired_name,
sspi_gss_OID desired_mech,
sspi_gss_cred_usage_t cred_usage,
UINT32 initiator_time_req,
UINT32 acceptor_time_req,
sspi_gss_cred_id_t* output_cred_handle,
sspi_gss_OID_set* actual_mechs,
UINT32* initiator_time_rec,
UINT32* acceptor_time_rec);
UINT32 SSPI_GSSAPI sspi_gss_inquire_cred_by_mech(
UINT32* minor_status,
sspi_gss_cred_id_t cred_handle,
sspi_gss_OID mech_type,
sspi_gss_name_t* name,
UINT32* initiator_lifetime,
UINT32* acceptor_lifetime,
sspi_gss_cred_usage_t* cred_usage);
typedef UINT32(SSPI_GSSAPI* fn_sspi_gss_inquire_cred_by_mech)(
UINT32* minor_status,
sspi_gss_cred_id_t cred_handle,
sspi_gss_OID mech_type,
sspi_gss_name_t* name,
UINT32* initiator_lifetime,
UINT32* acceptor_lifetime,
sspi_gss_cred_usage_t* cred_usage);
UINT32 SSPI_GSSAPI sspi_gss_export_sec_context(
UINT32* minor_status,
sspi_gss_ctx_id_t* context_handle,
sspi_gss_buffer_t interprocess_token);
typedef UINT32(SSPI_GSSAPI* fn_sspi_gss_export_sec_context)(
UINT32* minor_status,
sspi_gss_ctx_id_t* context_handle,
sspi_gss_buffer_t interprocess_token);
UINT32 SSPI_GSSAPI sspi_gss_import_sec_context(
UINT32* minor_status,
sspi_gss_buffer_t interprocess_token,
sspi_gss_ctx_id_t* context_handle);
typedef UINT32(SSPI_GSSAPI* fn_sspi_gss_import_sec_context)(
UINT32* minor_status,
sspi_gss_buffer_t interprocess_token,
sspi_gss_ctx_id_t* context_handle);
UINT32 SSPI_GSSAPI sspi_gss_release_oid(
UINT32* minor_status,
sspi_gss_OID* oid);
typedef UINT32(SSPI_GSSAPI* fn_sspi_gss_release_oid)(
UINT32* minor_status,
sspi_gss_OID* oid);
UINT32 SSPI_GSSAPI sspi_gss_create_empty_oid_set(
UINT32* minor_status,
sspi_gss_OID_set* oid_set);
typedef UINT32(SSPI_GSSAPI* fn_sspi_gss_create_empty_oid_set)(
UINT32* minor_status,
sspi_gss_OID_set* oid_set);
UINT32 SSPI_GSSAPI sspi_gss_add_oid_set_member(
UINT32* minor_status,
sspi_gss_OID member_oid,
sspi_gss_OID_set* oid_set);
typedef UINT32(SSPI_GSSAPI* fn_sspi_gss_add_oid_set_member)(
UINT32* minor_status,
sspi_gss_OID member_oid,
sspi_gss_OID_set* oid_set);
UINT32 SSPI_GSSAPI sspi_gss_test_oid_set_member(
UINT32* minor_status,
sspi_gss_OID member,
sspi_gss_OID_set set,
int* present);
typedef UINT32(SSPI_GSSAPI* fn_sspi_gss_test_oid_set_member)(
UINT32* minor_status,
sspi_gss_OID member,
sspi_gss_OID_set set,
int* present);
UINT32 SSPI_GSSAPI sspi_gss_str_to_oid(
UINT32* minor_status,
sspi_gss_buffer_t oid_str,
sspi_gss_OID* oid);
typedef UINT32(SSPI_GSSAPI* fn_sspi_gss_str_to_oid)(
UINT32* minor_status,
sspi_gss_buffer_t oid_str,
sspi_gss_OID* oid);
UINT32 SSPI_GSSAPI sspi_gss_oid_to_str(
UINT32* minor_status,
sspi_gss_OID oid,
sspi_gss_buffer_t oid_str);
typedef UINT32(SSPI_GSSAPI* fn_sspi_gss_oid_to_str)(
UINT32* minor_status,
sspi_gss_OID oid,
sspi_gss_buffer_t oid_str);
UINT32 SSPI_GSSAPI sspi_gss_inquire_names_for_mech(
UINT32* minor_status,
sspi_gss_OID mechanism,
sspi_gss_OID_set* name_types);
typedef UINT32(SSPI_GSSAPI* fn_sspi_gss_inquire_names_for_mech)(
UINT32* minor_status,
sspi_gss_OID mechanism,
sspi_gss_OID_set* name_types);
UINT32 SSPI_GSSAPI sspi_gss_inquire_mechs_for_name(
UINT32* minor_status,
const sspi_gss_name_t input_name,
sspi_gss_OID_set* mech_types);
typedef UINT32(SSPI_GSSAPI* fn_sspi_gss_inquire_mechs_for_name)(
UINT32* minor_status,
const sspi_gss_name_t input_name,
sspi_gss_OID_set* mech_types);
UINT32 SSPI_GSSAPI sspi_gss_sign(
UINT32* minor_status,
sspi_gss_ctx_id_t context_handle,
int qop_req,
sspi_gss_buffer_t message_buffer,
sspi_gss_buffer_t message_token);
typedef UINT32(SSPI_GSSAPI* fn_sspi_gss_sign)(
UINT32* minor_status,
sspi_gss_ctx_id_t context_handle,
int qop_req,
sspi_gss_buffer_t message_buffer,
sspi_gss_buffer_t message_token);
UINT32 SSPI_GSSAPI sspi_gss_verify(
UINT32* minor_status,
sspi_gss_ctx_id_t context_handle,
sspi_gss_buffer_t message_buffer,
sspi_gss_buffer_t token_buffer,
int* qop_state);
typedef UINT32(SSPI_GSSAPI* fn_sspi_gss_verify)(
UINT32* minor_status,
sspi_gss_ctx_id_t context_handle,
sspi_gss_buffer_t message_buffer,
sspi_gss_buffer_t token_buffer,
int* qop_state);
UINT32 SSPI_GSSAPI sspi_gss_seal(
UINT32* minor_status,
sspi_gss_ctx_id_t context_handle,
int conf_req_flag,
int qop_req,
sspi_gss_buffer_t input_message_buffer,
int* conf_state,
sspi_gss_buffer_t output_message_buffer);
typedef UINT32(SSPI_GSSAPI* fn_sspi_gss_seal)(
UINT32* minor_status,
sspi_gss_ctx_id_t context_handle,
int conf_req_flag,
int qop_req,
sspi_gss_buffer_t input_message_buffer,
int* conf_state,
sspi_gss_buffer_t output_message_buffer);
UINT32 SSPI_GSSAPI sspi_gss_unseal(
UINT32* minor_status,
sspi_gss_ctx_id_t context_handle,
sspi_gss_buffer_t input_message_buffer,
sspi_gss_buffer_t output_message_buffer,
int* conf_state,
int* qop_state);
typedef UINT32(SSPI_GSSAPI* fn_sspi_gss_unseal)(
UINT32* minor_status,
sspi_gss_ctx_id_t context_handle,
sspi_gss_buffer_t input_message_buffer,
sspi_gss_buffer_t output_message_buffer,
int* conf_state,
int* qop_state);
UINT32 SSPI_GSSAPI sspi_gss_export_name(
UINT32* minor_status,
const sspi_gss_name_t input_name,
sspi_gss_buffer_t exported_name);
typedef UINT32(SSPI_GSSAPI* fn_sspi_gss_export_name)(
UINT32* minor_status,
const sspi_gss_name_t input_name,
sspi_gss_buffer_t exported_name);
UINT32 SSPI_GSSAPI sspi_gss_duplicate_name(
UINT32* minor_status,
const sspi_gss_name_t input_name,
sspi_gss_name_t* dest_name);
typedef UINT32(SSPI_GSSAPI* fn_sspi_gss_duplicate_name)(
UINT32* minor_status,
const sspi_gss_name_t input_name,
sspi_gss_name_t* dest_name);
UINT32 SSPI_GSSAPI sspi_gss_canonicalize_name(
UINT32* minor_status,
const sspi_gss_name_t input_name,
const sspi_gss_OID mech_type,
sspi_gss_name_t* output_name);
typedef UINT32(SSPI_GSSAPI* fn_sspi_gss_canonicalize_name)(
UINT32* minor_status,
const sspi_gss_name_t input_name,
const sspi_gss_OID mech_type,
sspi_gss_name_t* output_name);
UINT32 SSPI_GSSAPI sspi_gss_pseudo_random(
UINT32* minor_status,
sspi_gss_ctx_id_t context,
int prf_key,
const sspi_gss_buffer_t prf_in,
ssize_t desired_output_len,
sspi_gss_buffer_t prf_out);
typedef UINT32(SSPI_GSSAPI* fn_sspi_gss_pseudo_random)(
UINT32* minor_status,
sspi_gss_ctx_id_t context,
int prf_key,
const sspi_gss_buffer_t prf_in,
ssize_t desired_output_len,
sspi_gss_buffer_t prf_out);
UINT32 SSPI_GSSAPI sspi_gss_store_cred(
UINT32* minor_status,
const sspi_gss_cred_id_t input_cred_handle,
sspi_gss_cred_usage_t input_usage,
const sspi_gss_OID desired_mech,
UINT32 overwrite_cred,
UINT32 default_cred,
sspi_gss_OID_set* elements_stored,
sspi_gss_cred_usage_t* cred_usage_stored);
typedef UINT32(SSPI_GSSAPI* fn_sspi_gss_store_cred)(
UINT32* minor_status,
const sspi_gss_cred_id_t input_cred_handle,
sspi_gss_cred_usage_t input_usage,
const sspi_gss_OID desired_mech,
UINT32 overwrite_cred,
UINT32 default_cred,
sspi_gss_OID_set* elements_stored,
sspi_gss_cred_usage_t* cred_usage_stored);
UINT32 SSPI_GSSAPI sspi_gss_set_neg_mechs(
UINT32* minor_status,
sspi_gss_cred_id_t cred_handle,
const sspi_gss_OID_set mech_set);
typedef UINT32(SSPI_GSSAPI* fn_sspi_gss_set_neg_mechs)(
UINT32* minor_status,
sspi_gss_cred_id_t cred_handle,
const sspi_gss_OID_set mech_set);
#ifdef __cplusplus
}
#endif
struct _GSSAPI_FUNCTION_TABLE
{
fn_sspi_gss_acquire_cred gss_acquire_cred;
fn_sspi_gss_release_cred gss_release_cred;
fn_sspi_gss_init_sec_context gss_init_sec_context;
fn_sspi_gss_accept_sec_context gss_accept_sec_context;
fn_sspi_gss_process_context_token gss_process_context_token;
fn_sspi_gss_delete_sec_context gss_delete_sec_context;
fn_sspi_gss_context_time gss_context_time;
fn_sspi_gss_get_mic gss_get_mic;
fn_sspi_gss_verify_mic gss_verify_mic;
fn_sspi_gss_wrap gss_wrap;
fn_sspi_gss_unwrap gss_unwrap;
fn_sspi_gss_display_status gss_display_status;
fn_sspi_gss_indicate_mechs gss_indicate_mechs;
fn_sspi_gss_compare_name gss_compare_name;
fn_sspi_gss_display_name gss_display_name;
fn_sspi_gss_import_name gss_import_name;
fn_sspi_gss_release_name gss_release_name;
fn_sspi_gss_release_buffer gss_release_buffer;
fn_sspi_gss_release_oid_set gss_release_oid_set;
fn_sspi_gss_inquire_cred gss_inquire_cred;
fn_sspi_gss_inquire_context gss_inquire_context;
fn_sspi_gss_wrap_size_limit gss_wrap_size_limit;
fn_sspi_gss_import_name_object gss_import_name_object;
fn_sspi_gss_export_name_object gss_export_name_object;
fn_sspi_gss_add_cred gss_add_cred;
fn_sspi_gss_inquire_cred_by_mech gss_inquire_cred_by_mech;
fn_sspi_gss_export_sec_context gss_export_sec_context;
fn_sspi_gss_import_sec_context gss_import_sec_context;
fn_sspi_gss_release_oid gss_release_oid;
fn_sspi_gss_create_empty_oid_set gss_create_empty_oid_set;
fn_sspi_gss_add_oid_set_member gss_add_oid_set_member;
fn_sspi_gss_test_oid_set_member gss_test_oid_set_member;
fn_sspi_gss_str_to_oid gss_str_to_oid;
fn_sspi_gss_oid_to_str gss_oid_to_str;
fn_sspi_gss_inquire_names_for_mech gss_inquire_names_for_mech;
fn_sspi_gss_inquire_mechs_for_name gss_inquire_mechs_for_name;
fn_sspi_gss_sign gss_sign;
fn_sspi_gss_verify gss_verify;
fn_sspi_gss_seal gss_seal;
fn_sspi_gss_unseal gss_unseal;
fn_sspi_gss_export_name gss_export_name;
fn_sspi_gss_duplicate_name gss_duplicate_name;
fn_sspi_gss_canonicalize_name gss_canonicalize_name;
fn_sspi_gss_pseudo_random gss_pseudo_random;
fn_sspi_gss_store_cred gss_store_cred;
fn_sspi_gss_set_neg_mechs gss_set_neg_mechs;
};
typedef struct _GSSAPI_FUNCTION_TABLE GSSAPI_FUNCTION_TABLE;
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif /* FREERDP_SSPI_GSS_PRIVATE_H */

File diff suppressed because it is too large Load Diff

View File

@ -37,7 +37,7 @@ int TestAcquireCredentialsHandle(int argc, char* argv[])
identity.PasswordLength = strlen(test_Password);
identity.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
status = table->AcquireCredentialsHandle(NULL, NTLMSP_NAME,
status = table->AcquireCredentialsHandle(NULL, NTLMSSP_NAME,
SECPKG_CRED_OUTBOUND, NULL, &identity, NULL, NULL, &credentials, &expiration);
if (status != SEC_E_OK)

View File

@ -29,7 +29,7 @@ int TestInitializeSecurityContext(int argc, char* argv[])
table = InitSecurityInterface();
status = QuerySecurityPackageInfo(NTLMSP_NAME, &pPackageInfo);
status = QuerySecurityPackageInfo(NTLMSSP_NAME, &pPackageInfo);
if (status != SEC_E_OK)
{
@ -56,7 +56,7 @@ int TestInitializeSecurityContext(int argc, char* argv[])
identity.PasswordLength = strlen(test_Password);
identity.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
status = table->AcquireCredentialsHandle(NULL, NTLMSP_NAME,
status = table->AcquireCredentialsHandle(NULL, NTLMSSP_NAME,
SECPKG_CRED_OUTBOUND, NULL, &identity, NULL, NULL, &credentials, &expiration);
if (status != SEC_E_OK)

View File

@ -72,8 +72,7 @@ static const BYTE TEST_NTLM_HASH[16] =
static const BYTE TEST_NTLM_V2_HASH[16] =
{ 0x4c, 0x7f, 0x70, 0x6f, 0x7d, 0xde, 0x05, 0xa9, 0xd1, 0xa0, 0xf4, 0xe7, 0xff, 0xe3, 0xbf, 0xb8 };
//#define NTLM_PACKAGE_NAME NEGOSSP_NAME
#define NTLM_PACKAGE_NAME NTLMSP_NAME
#define NTLM_PACKAGE_NAME NTLMSSP_NAME
struct _TEST_NTLM_CLIENT
{

View File

@ -11,7 +11,7 @@ int TestQuerySecurityPackageInfo(int argc, char* argv[])
sspi_GlobalInit();
status = QuerySecurityPackageInfo(NTLMSP_NAME, &pPackageInfo);
status = QuerySecurityPackageInfo(NTLMSSP_NAME, &pPackageInfo);
if (status != SEC_E_OK)
{