Add support for RFC5801 rfc5801
authorSimo Sorce <simo@redhat.com>
Thu, 18 Apr 2019 18:09:32 +0000 (14:09 -0400)
committerSimo Sorce <simo@redhat.com>
Thu, 18 Apr 2019 18:09:32 +0000 (14:09 -0400)
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 <simo@redhat.com>
src/gss_names.c
src/gss_ntlmssp.h
src/gss_spi.c
tests/ntlmssptest.c

index a663d219b9eca5132c8e7454ddcc1c8eff76994d..7e7eaca1c4b066d527d283dae8707cc5552edfa5 100644 (file)
@@ -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;
+
+}
index 991546532570acdadd4c8f9927aba4ca6bf552c5..3dde0f65a95a4e0d14e8c286a861d6bc2a033a3c 100644 (file)
@@ -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_ */
index c03b1a94f774ba0251a2d30ebf83e68b0240641e..8c9dd8ee05c73e092f475278f69e3a0339222f36 100644 (file)
@@ -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);
+}
index f15c403a2c8cbfafee213c4fc044b26ab95e687e..e8c4d5883af055745864153ef0ea254033226b79 100644 (file)
@@ -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;