{
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;
+
+}
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_ */
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);
+}
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;
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;