|
20 | 20 | #include <assert.h>
|
21 | 21 | #include <string.h>
|
22 | 22 |
|
| 23 | +#if defined(GSS_SHIM) |
| 24 | +#include <dlfcn.h> |
| 25 | +#include "pal_atomic.h" |
| 26 | +#endif |
| 27 | + |
23 | 28 | c_static_assert(PAL_GSS_C_DELEG_FLAG == GSS_C_DELEG_FLAG);
|
24 | 29 | c_static_assert(PAL_GSS_C_MUTUAL_FLAG == GSS_C_MUTUAL_FLAG);
|
25 | 30 | c_static_assert(PAL_GSS_C_REPLAY_FLAG == GSS_C_REPLAY_FLAG);
|
@@ -48,6 +53,103 @@ static gss_OID_desc gss_mech_ntlm_OID_desc = {.length = ARRAY_SIZE(gss_ntlm_oid_
|
48 | 53 | .elements = gss_ntlm_oid_value};
|
49 | 54 | #endif
|
50 | 55 |
|
| 56 | +#if defined(GSS_SHIM) |
| 57 | + |
| 58 | +#define FOR_ALL_GSS_FUNCTIONS \ |
| 59 | + PER_FUNCTION_BLOCK(gss_accept_sec_context) \ |
| 60 | + PER_FUNCTION_BLOCK(gss_acquire_cred) \ |
| 61 | + PER_FUNCTION_BLOCK(gss_acquire_cred_with_password) \ |
| 62 | + PER_FUNCTION_BLOCK(gss_delete_sec_context) \ |
| 63 | + PER_FUNCTION_BLOCK(gss_display_name) \ |
| 64 | + PER_FUNCTION_BLOCK(gss_display_status) \ |
| 65 | + PER_FUNCTION_BLOCK(gss_import_name) \ |
| 66 | + PER_FUNCTION_BLOCK(gss_indicate_mechs) \ |
| 67 | + PER_FUNCTION_BLOCK(gss_init_sec_context) \ |
| 68 | + PER_FUNCTION_BLOCK(gss_inquire_context) \ |
| 69 | + PER_FUNCTION_BLOCK(gss_mech_krb5) \ |
| 70 | + PER_FUNCTION_BLOCK(gss_oid_equal) \ |
| 71 | + PER_FUNCTION_BLOCK(gss_release_buffer) \ |
| 72 | + PER_FUNCTION_BLOCK(gss_release_cred) \ |
| 73 | + PER_FUNCTION_BLOCK(gss_release_name) \ |
| 74 | + PER_FUNCTION_BLOCK(gss_release_oid_set) \ |
| 75 | + PER_FUNCTION_BLOCK(gss_unwrap) \ |
| 76 | + PER_FUNCTION_BLOCK(gss_wrap) \ |
| 77 | + PER_FUNCTION_BLOCK(GSS_C_NT_USER_NAME) \ |
| 78 | + PER_FUNCTION_BLOCK(GSS_C_NT_HOSTBASED_SERVICE) |
| 79 | + |
| 80 | +#if HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X |
| 81 | + |
| 82 | +#define FOR_ALL_GSS_FUNCTIONS FOR_ALL_GSS_FUNCTIONS \ |
| 83 | + PER_FUNCTION_BLOCK(gss_set_cred_option) |
| 84 | + |
| 85 | +#endif //HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X |
| 86 | + |
| 87 | +// define indirection pointers for all functions, like |
| 88 | +// static TYPEOF(gss_accept_sec_context)* gss_accept_sec_context_ptr; |
| 89 | +#define PER_FUNCTION_BLOCK(fn) \ |
| 90 | +static TYPEOF(fn)* fn##_ptr; |
| 91 | + |
| 92 | +FOR_ALL_GSS_FUNCTIONS |
| 93 | +#undef PER_FUNCTION_BLOCK |
| 94 | + |
| 95 | +static void* volatile s_gssLib = NULL; |
| 96 | + |
| 97 | +// remap gss function use to use indirection pointers |
| 98 | +#define gss_accept_sec_context(...) gss_accept_sec_context_ptr(__VA_ARGS__) |
| 99 | +#define gss_acquire_cred(...) gss_acquire_cred_ptr(__VA_ARGS__) |
| 100 | +#define gss_acquire_cred_with_password(...) gss_acquire_cred_with_password_ptr(__VA_ARGS__) |
| 101 | +#define gss_delete_sec_context(...) gss_delete_sec_context_ptr(__VA_ARGS__) |
| 102 | +#define gss_display_name(...) gss_display_name_ptr(__VA_ARGS__) |
| 103 | +#define gss_display_status(...) gss_display_status_ptr(__VA_ARGS__) |
| 104 | +#define gss_import_name(...) gss_import_name_ptr(__VA_ARGS__) |
| 105 | +#define gss_indicate_mechs(...) gss_indicate_mechs_ptr(__VA_ARGS__) |
| 106 | +#define gss_init_sec_context(...) gss_init_sec_context_ptr(__VA_ARGS__) |
| 107 | +#define gss_inquire_context(...) gss_inquire_context_ptr(__VA_ARGS__) |
| 108 | +#define gss_oid_equal(...) gss_oid_equal_ptr(__VA_ARGS__) |
| 109 | +#define gss_release_buffer(...) gss_release_buffer_ptr(__VA_ARGS__) |
| 110 | +#define gss_release_cred(...) gss_release_cred_ptr(__VA_ARGS__) |
| 111 | +#define gss_release_name(...) gss_release_name_ptr(__VA_ARGS__) |
| 112 | +#define gss_release_oid_set(...) gss_release_oid_set_ptr(__VA_ARGS__) |
| 113 | +#define gss_unwrap(...) gss_unwrap_ptr(__VA_ARGS__) |
| 114 | +#define gss_wrap(...) gss_wrap_ptr(__VA_ARGS__) |
| 115 | + |
| 116 | +#if HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X |
| 117 | +#define gss_set_cred_option(...) gss_set_cred_option_ptr(__VA_ARGS__) |
| 118 | +#endif //HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X |
| 119 | + |
| 120 | + |
| 121 | +#define GSS_C_NT_USER_NAME (*GSS_C_NT_USER_NAME_ptr) |
| 122 | +#define GSS_C_NT_HOSTBASED_SERVICE (*GSS_C_NT_HOSTBASED_SERVICE_ptr) |
| 123 | +#define gss_mech_krb5 (*gss_mech_krb5_ptr) |
| 124 | + |
| 125 | +#define gss_lib_name "libgssapi_krb5.so" |
| 126 | + |
| 127 | +static int32_t ensure_gss_shim_initialized() |
| 128 | +{ |
| 129 | + void* lib = dlopen(gss_lib_name, RTLD_LAZY); |
| 130 | + if (lib == NULL) { fprintf(stderr, "Cannot load library %s \nError: %s\n", gss_lib_name, dlerror()); return -1; } |
| 131 | + |
| 132 | + // check is someone else has opened and published s_gssLib already |
| 133 | + if (!pal_atomic_cas_ptr(&s_gssLib, lib, NULL)) |
| 134 | + { |
| 135 | + dlclose(lib); |
| 136 | + } |
| 137 | + |
| 138 | + // initialize indirection pointers for all functions, like: |
| 139 | + // gss_accept_sec_context_ptr = (TYPEOF(gss_accept_sec_context)*)dlsym(s_gssLib, "gss_accept_sec_context"); |
| 140 | + // if (gss_accept_sec_context_ptr == NULL) { fprintf(stderr, "Cannot get symbol %s from %s \nError: %s\n", "gss_accept_sec_context", gss_lib_name, dlerror()); return -1; } |
| 141 | +#define PER_FUNCTION_BLOCK(fn) \ |
| 142 | + fn##_ptr = (TYPEOF(fn)*)dlsym(s_gssLib, #fn); \ |
| 143 | + if (fn##_ptr == NULL) { fprintf(stderr, "Cannot get symbol " #fn " from %s \nError: %s\n", gss_lib_name, dlerror()); return -1; } |
| 144 | + |
| 145 | + FOR_ALL_GSS_FUNCTIONS |
| 146 | +#undef PER_FUNCTION_BLOCK |
| 147 | + |
| 148 | + return 0; |
| 149 | +} |
| 150 | + |
| 151 | +#endif // GSS_SHIM |
| 152 | + |
51 | 153 | // transfers ownership of the underlying data from gssBuffer to PAL_GssBuffer
|
52 | 154 | static void NetSecurityNative_MoveBuffer(gss_buffer_t gssBuffer, PAL_GssBuffer* targetBuffer)
|
53 | 155 | {
|
@@ -567,3 +669,12 @@ uint32_t NetSecurityNative_IsNtlmInstalled()
|
567 | 669 |
|
568 | 670 | return foundNtlm;
|
569 | 671 | }
|
| 672 | + |
| 673 | +int32_t NetSecurityNative_EnsureGssInitialized() |
| 674 | +{ |
| 675 | +#if defined(GSS_SHIM) |
| 676 | + return ensure_gss_shim_initialized(); |
| 677 | +#else |
| 678 | + return 0; |
| 679 | +#endif |
| 680 | +} |
0 commit comments