static const gss_OID_desc auth_gssapi_mech_krb5_oid_desc =
{ 9, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02" };
+static const gss_OID_desc auth_gssapi_mech_spnego_oid_desc =
+ { 6, "\x2b\x06\x01\x05\x05\x02" };
const gss_OID_desc *auth_gssapi_mech_krb5_oid =
&auth_gssapi_mech_krb5_oid_desc;
+const gss_OID_desc *auth_gssapi_mech_spnego_oid =
+ &auth_gssapi_mech_spnego_oid_desc;
bool auth_gssapi_oid_equal(const gss_OID_desc *oid1, const gss_OID_desc *oid2)
{
#endif
extern const gss_OID_desc *auth_gssapi_mech_krb5_oid;
+extern const gss_OID_desc *auth_gssapi_mech_spnego_oid;
bool auth_gssapi_oid_equal(const gss_OID_desc *oid1, const gss_OID_desc *oid2);
buffer_t *out_buf;
};
+static const struct dsasl_client_mech dsasl_client_mech_gssapi;
+static const struct dsasl_client_mech dsasl_client_mech_gss_spnego;
+
static void
mech_gssapi_error_append(string_t *msg, unsigned int *entries,
OM_uint32 status_value, int status_type)
OM_uint32 major_status, minor_status;
OM_uint32 req_flags = GSS_C_REPLAY_FLAG | GSS_C_MUTUAL_FLAG |
GSS_C_SEQUENCE_FLAG | GSS_C_INTEG_FLAG;
- gss_OID_desc mech_oid = *auth_gssapi_mech_krb5_oid;
+ gss_OID_desc mech_oid;
gss_OID ret_mech_oid;
+ if (client->mech == &dsasl_client_mech_gssapi)
+ mech_oid = *auth_gssapi_mech_krb5_oid;
+ else if (client->mech == &dsasl_client_mech_gss_spnego)
+ mech_oid = *auth_gssapi_mech_spnego_oid;
+ else
+ i_unreached();
+
major_status = gss_init_sec_context(&minor_status, GSS_C_NO_CREDENTIAL,
&gclient->gss_ctx,
gclient->gss_principal,
.free = mech_gssapi_free,
};
+static const struct dsasl_client_mech dsasl_client_mech_gss_spnego = {
+ .name = "GSS-SPNEGO",
+ .flags = DSASL_MECH_SEC_ALLOW_NULS,
+ .struct_size = sizeof(struct gssapi_sasl_client),
+
+ .input = mech_gssapi_gs1_input,
+ .output = mech_gssapi_gs1_output,
+ .free = mech_gssapi_free,
+};
+
static bool initialized = FALSE;
void dsasl_clients_init_gssapi(void)
initialized = TRUE;
dsasl_client_mech_register(&dsasl_client_mech_gssapi);
+ dsasl_client_mech_register(&dsasl_client_mech_gss_spnego);
}
i_zero(&result);
#ifdef HAVE_GSSAPI
- if (strcmp(fctx->params->mech, SASL_MECH_NAME_GSSAPI) == 0) {
+ if (strcmp(fctx->params->mech, SASL_MECH_NAME_GSSAPI) == 0 ||
+ strcmp(fctx->params->mech, SASL_MECH_NAME_GSS_SPNEGO) == 0) {
i_assert(*scheme == '\0');
result.status = SASL_PASSDB_RESULT_OK;
callback(&fctx->ssrctx, &result);
i_zero(&gssapi_set);
gssapi_set.hostname = "localhost";
sasl_server_mech_register_gssapi(server_inst, &gssapi_set);
+ sasl_server_mech_register_gss_spnego(server_inst, &gssapi_set);
#endif
const struct sasl_server_mech *server_mech;
e_debug(fuzz_event, "run: %s", str_sanitize(params.mech, 1024));
#ifdef HAVE_GSSAPI
- if (strcmp(params.mech, SASL_MECH_NAME_GSSAPI) == 0) {
+ if (strcmp(params.mech, SASL_MECH_NAME_GSSAPI) == 0 ||
+ strcmp(params.mech, SASL_MECH_NAME_GSS_SPNEGO) == 0) {
gss_dummy_add_principal(params.authid);
gss_dummy_kinit(params.authid);
}
ctx->req_flags = req_flags;
ctx->mech_type = *mech_type;
+ /* Morph SPNEGO into normal Kerberos5 */
+ if (auth_gssapi_oid_equal(&ctx->mech_type, auth_gssapi_mech_spnego_oid))
+ ctx->mech_type = *auth_gssapi_mech_krb5_oid;
+
size_t src_name_len = strlen(ctx->src_name);
size_t cbind_len = 0;
if (input_chan_bindings != GSS_C_NO_CHANNEL_BINDINGS) {
i_zero(&result);
#ifdef HAVE_GSSAPI
- if (strcmp(tctx->test->mech, SASL_MECH_NAME_GSSAPI) == 0) {
+ if (strcmp(tctx->test->mech, SASL_MECH_NAME_GSSAPI) == 0 ||
+ strcmp(tctx->test->mech, SASL_MECH_NAME_GSS_SPNEGO) == 0) {
i_assert(*scheme == '\0');
result.status = SASL_PASSDB_RESULT_OK;
callback(&tctx->ssrctx, &result);
i_zero(&gssapi_set);
gssapi_set.hostname = "localhost";
sasl_server_mech_register_gssapi(server_inst, &gssapi_set);
+ sasl_server_mech_register_gss_spnego(server_inst, &gssapi_set);
#endif
const struct sasl_server_mech *server_mech;
i_assert(server_mech != NULL);
#ifdef HAVE_GSSAPI
- if (strcmp(test->mech, SASL_MECH_NAME_GSSAPI) == 0) {
+ if (strcmp(test->mech, SASL_MECH_NAME_GSSAPI) == 0 ||
+ strcmp(test->mech, SASL_MECH_NAME_GSS_SPNEGO) == 0) {
gss_dummy_add_principal(test->server.authid);
gss_dummy_kinit(test->client.authid != NULL ?
test->client.authid : test->server.authid);
.password = "",
},
},
+ {
+ .mech = "GSS-SPNEGO",
+ .authid_type = SASL_SERVER_AUTHID_TYPE_USERNAME,
+ .server = {
+ .authid = "user",
+ .password = "",
+ },
+ },
#endif
/* NTLM */
{
},
.failure = TRUE,
},
+ /* GSS-SPNEGO */
+ {
+ .mech = "GSS-SPNEGO",
+ .authid_type = SASL_SERVER_AUTHID_TYPE_USERNAME,
+ .server = {
+ .authid = "user",
+ .password = "",
+ },
+ .client = {
+ .authid = "userb",
+ },
+ .failure = TRUE,
+ },
#endif
/* NTLM */
{