From 17ce6893fffbd3d1d27a23eba06b9e586aef5bb1 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Apr 18 2019 18:09:32 +0000 Subject: Add support for RFC5801 These are the only GSS-API functions that can return a mechanism name given an oid. These are now used by mod_auth_gssapi, so let's support them in gssntlmssp. Signed-off-by: Simo Sorce --- diff --git a/src/gss_names.c b/src/gss_names.c index a663d21..7e7eaca 100644 --- a/src/gss_names.c +++ b/src/gss_names.c @@ -643,3 +643,75 @@ uint32_t gssntlm_inquire_name(uint32_t *minor_status, { return GSS_S_UNAVAILABLE; } + +/* RFC5801 Extensions */ + +#define GS2_NTLM_SASL_NAME "GS2-NTLM" +#define GS2_NTLM_SASL_NAME_LEN (sizeof(GS2_NTLM_SASL_NAME) - 1) + +uint32_t gssntlm_inquire_saslname_for_mech(OM_uint32 *minor_status, + const gss_OID desired_mech, + gss_buffer_t sasl_mech_name, + gss_buffer_t mech_name, + gss_buffer_t mech_description) +{ + if (desired_mech && !gss_oid_equal(desired_mech, &gssntlm_oid)) { + *minor_status = ENOENT; + return GSS_S_BAD_MECH; + } + + sasl_mech_name->value = NULL; + mech_name->value = NULL; + mech_description->value = NULL; + + *minor_status = ENOMEM; + + sasl_mech_name->value = strdup(GS2_NTLM_SASL_NAME); + if (sasl_mech_name->value == NULL) { + goto done; + } + sasl_mech_name->length = strlen(sasl_mech_name->value); + + mech_name->value = strdup("NTLM"); + if (mech_name->value == NULL) { + goto done; + } + mech_name->length = strlen(mech_name->value); + + mech_description->value = strdup("NTLM Mechanism"); + if (mech_name->value == NULL) { + goto done; + } + mech_description->length = strlen(mech_description->value); + + *minor_status = 0; + +done: + if (*minor_status != 0) { + free(sasl_mech_name->value); + free(mech_name->value); + free(mech_description->value); + return GSS_S_FAILURE; + } + + return GSS_S_COMPLETE; +} + +uint32_t gssntlm_inquire_mech_for_saslname(OM_uint32 *minor_status, + const gss_buffer_t sasl_mech_name, + gss_OID *mech_type) +{ + if (sasl_mech_name->length == GS2_NTLM_SASL_NAME_LEN && + memcmp(sasl_mech_name->value, + GS2_NTLM_SASL_NAME, GS2_NTLM_SASL_NAME_LEN) == 0) { + if (mech_type != NULL) { + *mech_type = discard_const(&gssntlm_oid); + } + *minor_status = 0; + return GSS_S_COMPLETE; + } + + *minor_status = ENOENT; + return GSS_S_BAD_MECH; + +} diff --git a/src/gss_ntlmssp.h b/src/gss_ntlmssp.h index 9915465..3dde0f6 100644 --- a/src/gss_ntlmssp.h +++ b/src/gss_ntlmssp.h @@ -421,4 +421,15 @@ uint32_t gssntlm_inquire_name(uint32_t *minor_status, int *name_is_MN, gss_OID *MN_mech, gss_buffer_set_t *attrs); + +uint32_t gssntlm_inquire_saslname_for_mech(OM_uint32 *minor_status, + const gss_OID desired_mech, + gss_buffer_t sasl_mech_name, + gss_buffer_t mech_name, + gss_buffer_t mech_description); + +uint32_t gssntlm_inquire_mech_for_saslname(OM_uint32 *minor_status, + const gss_buffer_t sasl_mech_name, + gss_OID *mech_type); + #endif /* _GSS_NTLMSSP_H_ */ diff --git a/src/gss_spi.c b/src/gss_spi.c index c03b1a9..8c9dd8e 100644 --- a/src/gss_spi.c +++ b/src/gss_spi.c @@ -418,3 +418,22 @@ OM_uint32 gss_inquire_name(OM_uint32 *minor_status, return gssntlm_inquire_name(minor_status, name, name_is_MN, MN_mech, attrs); } + +OM_uint32 gss_inquire_saslname_for_mech(OM_uint32 *minor_status, + const gss_OID desired_mech, + gss_buffer_t sasl_mech_name, + gss_buffer_t mech_name, + gss_buffer_t mech_description) +{ + return gssntlm_inquire_saslname_for_mech(minor_status, desired_mech, + sasl_mech_name, mech_name, + mech_description); +} + +OM_uint32 gss_inquire_mech_for_saslname(OM_uint32 *minor_status, + const gss_buffer_t sasl_mech_name, + gss_OID *mech_type) +{ + return gssntlm_inquire_mech_for_saslname(minor_status, sasl_mech_name, + mech_type); +} diff --git a/tests/ntlmssptest.c b/tests/ntlmssptest.c index f15c403..e8c4d58 100644 --- a/tests/ntlmssptest.c +++ b/tests/ntlmssptest.c @@ -1998,6 +1998,50 @@ done: return ret; } +int test_gssapi_rfc5801(void) +{ + gss_buffer_desc sasl_name = { 8, discard_const("GS2-NTLM") }; + gss_buffer_desc mech_name; + gss_buffer_desc mech_desc; + gss_OID oid; + uint32_t retmin, retmaj; + + retmaj = gssntlm_inquire_mech_for_saslname(&retmin, &sasl_name, &oid); + if (retmaj != GSS_S_COMPLETE) { + print_gss_error("gssntlm_inquire_mech_for_saslname() failed!", + retmaj, retmin); + return EINVAL; + } + + retmaj = gssntlm_inquire_saslname_for_mech(&retmin, oid, &sasl_name, + &mech_name, &mech_desc); + if (retmaj != GSS_S_COMPLETE) { + print_gss_error("gssntlm_inquire_saslname_for_mech() failed!", + retmaj, retmin); + return EINVAL; + } + + if (strncmp(sasl_name.value, "GS2-NTLM", 8)) { + fprintf(stderr, "Expected 'GS2-NTLM', got: '%.*s'\n", + (int)sasl_name.length, (char *)sasl_name.value); + return EINVAL; + } + + if (strncmp(mech_name.value, "NTLM", 8)) { + fprintf(stderr, "Expected 'NTLM', got: '%.*s'\n", + (int)mech_name.length, (char *)mech_name.value); + return EINVAL; + } + + if (strncmp(mech_desc.value, "NTLM Mechanism", 8)) { + fprintf(stderr, "Expected 'NTLM Mechanism', got: '%.*s'\n", + (int)mech_desc.length, (char *)mech_desc.value); + return EINVAL; + } + + return 0; +} + int main(int argc, const char *argv[]) { struct ntlm_ctx *ctx; @@ -2161,6 +2205,10 @@ int main(int argc, const char *argv[]) ret = test_gssapi_cl(); fprintf(stdout, "Test: %s\n", (ret ? "FAIL":"SUCCESS")); + fprintf(stdout, "Test RFC5801 SPI\n"); + ret = test_gssapi_rfc5801(); + fprintf(stdout, "Test: %s\n", (ret ? "FAIL":"SUCCESS")); + done: ntlm_free_ctx(&ctx); return ret;