initial commit for kerberos support
This commit is contained in:
parent
ff59cf028c
commit
b81f168f0e
@ -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)
|
||||
|
@ -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")
|
||||
|
@ -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")
|
||||
|
@ -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
288
cmake/FindGSSAPI.cmake
Normal 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)
|
@ -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)
|
||||
|
||||
|
@ -61,7 +61,6 @@
|
||||
/* Plugins */
|
||||
#cmakedefine BUILTIN_CHANNELS
|
||||
#cmakedefine WITH_RDPDR
|
||||
#cmakedefine WITH_KRB5
|
||||
|
||||
/* Debug */
|
||||
#cmakedefine WITH_DEBUG_CERTIFICATE
|
||||
|
@ -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()
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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))
|
||||
|
@ -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;
|
||||
|
@ -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()
|
||||
|
734
winpr/libwinpr/sspi/Kerberos/kerberos.c
Normal file
734
winpr/libwinpr/sspi/Kerberos/kerberos.c
Normal 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 */
|
||||
};
|
83
winpr/libwinpr/sspi/Kerberos/kerberos.h
Normal file
83
winpr/libwinpr/sspi/Kerberos/kerberos.h
Normal 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 */
|
@ -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)
|
||||
|
@ -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 =
|
||||
|
@ -44,6 +44,7 @@ struct _NEGOTIATE_CONTEXT
|
||||
|
||||
CtxtHandle SubContext;
|
||||
|
||||
BOOL kerberos;
|
||||
SecurityFunctionTableA* sspiA;
|
||||
SecurityFunctionTableW* sspiW;
|
||||
};
|
||||
|
@ -85,6 +85,7 @@ enum SecurityFunctionTableIndex
|
||||
|
||||
BOOL IsSecurityStatusError(SECURITY_STATUS status);
|
||||
|
||||
#include "sspi_gss.h"
|
||||
#include "sspi_winpr.h"
|
||||
|
||||
#endif /* WINPR_SSPI_PRIVATE_H */
|
||||
|
666
winpr/libwinpr/sspi/sspi_gss.c
Normal file
666
winpr/libwinpr/sspi/sspi_gss.c
Normal 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
|
||||
}
|
883
winpr/libwinpr/sspi/sspi_gss.h
Normal file
883
winpr/libwinpr/sspi/sspi_gss.h
Normal 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
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user