Skip to content

Commit 3dece8f

Browse files
committed
tolerate absence of API in gss_indicate_mechs. It may be used for API probing.
1 parent 7f88c8b commit 3dece8f

File tree

2 files changed

+36
-11
lines changed

2 files changed

+36
-11
lines changed

src/libraries/Native/Unix/System.Net.Security.Native/extra_libs.cmake

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@ macro(append_extra_security_libs NativeLibsExtra)
2222
if(CLR_CMAKE_TARGET_LINUX)
2323
# On Linux libgssapi_krb5.so is loaded on demand to tolerate its absense in singlefile apps that do not use it
2424
list(APPEND ${NativeLibsExtra} dl)
25-
add_definitions(-DGSS_SHIM)
26-
add_definitions(-DgssLibraryName="libgssapi_krb5.so")
25+
add_definitions(-DGSS_DYNAMIC_LIB="libgssapi_krb5.so")
2726
else()
2827
list(APPEND ${NativeLibsExtra} ${LIBGSS})
2928
endif()

src/libraries/Native/Unix/System.Net.Security.Native/pal_gssapi.c

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
#include <assert.h>
2121
#include <string.h>
2222

23-
#if defined(GSS_SHIM)
23+
#if defined(GSS_DYNAMIC_LIB)
2424
#include <dlfcn.h>
2525
#include "pal_atomic.h"
2626
#endif
@@ -53,7 +53,7 @@ static gss_OID_desc gss_mech_ntlm_OID_desc = {.length = ARRAY_SIZE(gss_ntlm_oid_
5353
.elements = gss_ntlm_oid_value};
5454
#endif
5555

56-
#if defined(GSS_SHIM)
56+
#if defined(GSS_DYNAMIC_LIB)
5757

5858
#define FOR_ALL_GSS_FUNCTIONS \
5959
PER_FUNCTION_BLOCK(gss_accept_sec_context) \
@@ -108,8 +108,8 @@ static gss_shim_t* volatile s_gss_shim_ptr = NULL;
108108

109109
static void init_gss_shim()
110110
{
111-
void* lib = dlopen(gssLibraryName, RTLD_LAZY);
112-
if (lib == NULL) { fprintf(stderr, "Cannot load library %s \nError: %s\n", gssLibraryName, dlerror()); abort(); }
111+
void* lib = dlopen(GSS_DYNAMIC_LIB, RTLD_LAZY);
112+
if (lib == NULL) { fprintf(stderr, "Cannot load library %s \nError: %s\n", GSS_DYNAMIC_LIB, dlerror()); abort(); }
113113

114114
// check is someone else has opened and published s_gssLib already
115115
if (!pal_atomic_cas_ptr(&s_gssLib, lib, NULL))
@@ -119,10 +119,10 @@ static void init_gss_shim()
119119

120120
// initialize indirection pointers for all functions, like:
121121
// s_gss_shim.gss_accept_sec_context_ptr = (TYPEOF(gss_accept_sec_context)*)dlsym(s_gssLib, "gss_accept_sec_context");
122-
// if (s_gss_shim.gss_accept_sec_context_ptr == NULL) { fprintf(stderr, "Cannot get symbol %s from %s \nError: %s\n", "gss_accept_sec_context", gssLibraryName, dlerror()); abort(); }
122+
// if (s_gss_shim.gss_accept_sec_context_ptr == NULL) { fprintf(stderr, "Cannot get symbol %s from %s \nError: %s\n", "gss_accept_sec_context", GSS_DYNAMIC_LIB, dlerror()); abort(); }
123123
#define PER_FUNCTION_BLOCK(fn) \
124124
s_gss_shim.fn##_ptr = (TYPEOF(fn)*)dlsym(s_gssLib, #fn); \
125-
if (s_gss_shim.fn##_ptr == NULL) { fprintf(stderr, "Cannot get symbol " #fn " from %s \nError: %s\n", gssLibraryName, dlerror()); abort(); }
125+
if (s_gss_shim.fn##_ptr == NULL) { fprintf(stderr, "Cannot get symbol " #fn " from %s \nError: %s\n", GSS_DYNAMIC_LIB, dlerror()); abort(); }
126126

127127
FOR_ALL_GSS_FUNCTIONS
128128
#undef PER_FUNCTION_BLOCK
@@ -151,7 +151,6 @@ static gss_shim_t* get_gss_shim()
151151
#define gss_display_name(...) get_gss_shim()->gss_display_name_ptr(__VA_ARGS__)
152152
#define gss_display_status(...) get_gss_shim()->gss_display_status_ptr(__VA_ARGS__)
153153
#define gss_import_name(...) get_gss_shim()->gss_import_name_ptr(__VA_ARGS__)
154-
#define gss_indicate_mechs(...) get_gss_shim()->gss_indicate_mechs_ptr(__VA_ARGS__)
155154
#define gss_init_sec_context(...) get_gss_shim()->gss_init_sec_context_ptr(__VA_ARGS__)
156155
#define gss_inquire_context(...) get_gss_shim()->gss_inquire_context_ptr(__VA_ARGS__)
157156
#define gss_oid_equal(...) get_gss_shim()->gss_oid_equal_ptr(__VA_ARGS__)
@@ -171,7 +170,34 @@ static gss_shim_t* get_gss_shim()
171170
#define GSS_C_NT_HOSTBASED_SERVICE *get_gss_shim()->GSS_C_NT_HOSTBASED_SERVICE_ptr
172171
#define gss_mech_krb5 *get_gss_shim()->gss_mech_krb5_ptr
173172

174-
#endif // GSS_SHIM
173+
// NB: Managed side may call IsNtlmInstalled, which in turn calls `gss_indicate_mechs` to probe for support and
174+
// treat all all exceptions same as `false`. Our own tests and platform detection do that.
175+
// So we will not abort if API is not there for `gss_indicate_mechs_ptr`, and return a failure code instead.
176+
static bool probe_gss_api()
177+
{
178+
if (s_gss_shim_ptr)
179+
{
180+
return true;
181+
}
182+
183+
void* lib = dlopen(GSS_DYNAMIC_LIB, RTLD_LAZY);
184+
if (lib == NULL)
185+
{
186+
return false;
187+
}
188+
189+
// check is someone else has opened and published s_gssLib already
190+
if (!pal_atomic_cas_ptr(&s_gssLib, lib, NULL))
191+
{
192+
dlclose(lib);
193+
}
194+
195+
return true;
196+
}
197+
198+
#define gss_indicate_mechs(...) (probe_gss_api() ? get_gss_shim()->gss_indicate_mechs_ptr(__VA_ARGS__) : GSS_S_UNAVAILABLE)
199+
200+
#endif // GSS_DYNAMIC_LIB
175201

176202
// transfers ownership of the underlying data from gssBuffer to PAL_GssBuffer
177203
static void NetSecurityNative_MoveBuffer(gss_buffer_t gssBuffer, PAL_GssBuffer* targetBuffer)
@@ -670,7 +696,7 @@ uint32_t NetSecurityNative_IsNtlmInstalled()
670696

671697
uint32_t majorStatus;
672698
uint32_t minorStatus;
673-
gss_OID_set mechSet;
699+
gss_OID_set mechSet = NULL;
674700
gss_OID_desc oid;
675701
uint32_t foundNtlm = 0;
676702

0 commit comments

Comments
 (0)