#include "gssdigest.h"
#include <gssapi_spi.h>
OM_uint32
_gss_scram_have_cred(OM_uint32 *minor,
const char *name,
gss_cred_id_t *rcred)
{
krb5_context context;
krb5_error_code ret;
krb5_storage *request = NULL, *response;
krb5_data response_data;
OM_uint32 major;
ret = krb5_init_context(&context);
if (ret) {
*minor = ret;
return GSS_S_FAILURE;
}
ret = krb5_kcm_storage_request(context, KCM_OP_HAVE_SCRAM_CRED, &request);
if (ret)
goto out;
ret = krb5_store_stringz(request, name);
if (ret)
goto out;
ret = krb5_kcm_call(context, request, &response, &response_data);
if (ret)
goto out;
request = NULL;
if (rcred) {
*rcred = (gss_cred_id_t)strdup(name);
if (*rcred == NULL)
ret = ENOMEM;
}
out:
if (request)
krb5_storage_free(request);
krb5_free_context(context);
if (ret) {
*minor = ret;
major = GSS_S_FAILURE;
} else
major = GSS_S_COMPLETE;
return major;
}
OM_uint32
_gss_scram_acquire_cred(OM_uint32 * min_stat,
const gss_name_t desired_name,
OM_uint32 time_req,
const gss_OID_set desired_mechs,
gss_cred_usage_t cred_usage,
gss_cred_id_t * output_cred_handle,
gss_OID_set * actual_mechs,
OM_uint32 * time_rec)
{
char *name = (char *) desired_name;
OM_uint32 maj_stat;
*min_stat = 0;
*output_cred_handle = GSS_C_NO_CREDENTIAL;
if (actual_mechs)
*actual_mechs = GSS_C_NO_OID_SET;
if (time_rec)
*time_rec = GSS_C_INDEFINITE;
if (desired_name == NULL)
return GSS_S_NO_CRED;
if (cred_usage == GSS_C_BOTH || cred_usage == GSS_C_ACCEPT) {
}
if (cred_usage == GSS_C_BOTH || cred_usage == GSS_C_INITIATE) {
maj_stat = _gss_scram_have_cred(min_stat, name, output_cred_handle);
if (maj_stat)
return maj_stat;
}
return (GSS_S_COMPLETE);
}
OM_uint32
_gss_scram_acquire_cred_ex(gss_status_id_t status,
const gss_name_t desired_name,
OM_uint32 flags,
OM_uint32 time_req,
gss_cred_usage_t cred_usage,
gss_auth_identity_t identity,
void *ctx,
void (*complete)(void *, OM_uint32, gss_status_id_t, gss_cred_id_t, OM_uint32))
{
krb5_storage *request, *response;
krb5_data response_data;
krb5_context context;
krb5_error_code ret;
char *cred;
krb5_data_zero(&response_data);
if (identity == NULL)
return GSS_S_FAILURE;
ret = krb5_init_context(&context);
if (ret)
return GSS_S_FAILURE;
ret = krb5_kcm_storage_request(context, KCM_OP_ADD_SCRAM_CRED, &request);
if (ret)
goto fail;
ret = krb5_store_stringz(request, identity->username);
if (ret)
goto fail;
ret = krb5_store_stringz(request, identity->password);
if (ret)
goto fail;
ret = krb5_kcm_call(context, request, &response, &response_data);
if (ret)
goto fail;
request = NULL;
asprintf(&cred, "%s", identity->username);
complete(ctx, GSS_S_COMPLETE, status, (gss_cred_id_t)cred, GSS_C_INDEFINITE);
if (response)
krb5_storage_free(response);
krb5_data_free(&response_data);
krb5_free_context(context);
return GSS_S_COMPLETE;
fail:
if (request)
krb5_storage_free(request);
return GSS_S_FAILURE;
}