kdc: add attribute dictionary to kdc_request_t

Add a heim_dict_t to the KDC request structure for use by pre-authentication
mechanisms and plugins.
This commit is contained in:
Luke Howard
2021-12-30 21:39:02 +11:00
parent b27026996a
commit a8ff420b16
10 changed files with 87 additions and 28 deletions

View File

@@ -882,6 +882,7 @@ set_req_desc(struct MHD_Connection *connection,
r->req_life = 0;
r->ret = 0;
r->kv = heim_dict_create(10);
r->attributes = heim_dict_create(1);
ci = MHD_get_connection_info(connection,
MHD_CONNECTION_INFO_CLIENT_ADDRESS);
if (ci) {

View File

@@ -66,6 +66,9 @@ pa_gss_display_name(gss_name_t name,
gss_buffer_t namebuf,
gss_const_buffer_t *namebuf_p);
static void
pa_gss_dealloc_client_params(void *ptr);
/*
* Create a checksum over KDC-REQ-BODY (without the nonce), used to
* assert the request is invariant within the preauth conversation.
@@ -421,7 +424,7 @@ _kdc_gss_rd_padata(astgs_request_t r,
goto out;
}
gcp = calloc(1, sizeof(*gcp));
gcp = heim_alloc(sizeof(*gcp), "pa-gss-client-params", pa_gss_dealloc_client_params);
if (gcp == NULL) {
ret = krb5_enomem(r->context);
goto out;
@@ -471,7 +474,7 @@ out:
if (gcp && gcp->major != GSS_S_NO_CONTEXT)
*pgcp = gcp;
else
_kdc_gss_free_client_param(r, gcp);
heim_release(gcp);
return ret;
}
@@ -864,10 +867,10 @@ _kdc_gss_mk_composite_name_ad(astgs_request_t r,
return ret;
}
void
_kdc_gss_free_client_param(astgs_request_t r,
gss_client_params *gcp)
static void
pa_gss_dealloc_client_params(void *ptr)
{
gss_client_params *gcp = ptr;
OM_uint32 minor;
if (gcp == NULL)
@@ -879,7 +882,6 @@ _kdc_gss_free_client_param(astgs_request_t r,
free_Checksum(&gcp->req_body_checksum);
krb5_data_free(&gcp->pac_data);
memset(gcp, 0, sizeof(*gcp));
free(gcp);
}
krb5_error_code

View File

@@ -1529,6 +1529,7 @@ set_req_desc(struct MHD_Connection *connection,
r->cname = NULL;
r->addr = NULL;
r->kv = heim_dict_create(10);
r->attributes = heim_dict_create(1);
/* Our fields */
r->connection = connection;
r->kadm_handle = NULL;

View File

@@ -64,7 +64,6 @@ struct kdc_request_desc {
HEIM_SVC_REQUEST_DESC_COMMON_ELEMENTS;
};
struct as_request_pa_state;
struct kdc_patypes;
struct astgs_request_desc {
@@ -72,7 +71,6 @@ struct astgs_request_desc {
/* Only AS */
const struct kdc_patypes *pa_used;
struct as_request_pa_state *pa_state;
/* PA methods can affect both the reply key and the session key (pkinit) */
krb5_enctype sessionetype;

View File

@@ -583,13 +583,13 @@ pa_gss_validate(astgs_request_t r, const PA_DATA *pa)
goto out;
}
heim_assert(r->pa_state == NULL, "already have PA state, should be NULL");
r->pa_state = (struct as_request_pa_state *)gcp;
gcp = NULL;
ret = krb5_kdc_request_set_attribute((kdc_request_t)r,
HSTR("org.h5l.pa-gss-client-params"), gcp);
if (ret)
goto out;
out:
if (gcp)
_kdc_gss_free_client_param(r, gcp);
heim_release(gcp);
free(client_name);
return ret;
@@ -598,24 +598,15 @@ out:
static krb5_error_code
pa_gss_finalize_pac(astgs_request_t r)
{
gss_client_params *gcp = (gss_client_params *)r->pa_state;
gss_client_params *gcp;
gcp = krb5_kdc_request_get_attribute((kdc_request_t)r, HSTR("org.h5l.pa-gss-client-params"));
heim_assert(gcp != NULL, "invalid GSS-API client params");
return _kdc_gss_finalize_pac(r, gcp);
}
static void
pa_gss_cleanup(astgs_request_t r)
{
gss_client_params *gcp = (gss_client_params *)r->pa_state;
if (gcp) {
_kdc_gss_free_client_param(r, gcp);
r->pa_state = NULL;
}
}
static krb5_error_code
pa_enc_chal_validate(astgs_request_t r, const PA_DATA *pa)
{
@@ -1009,7 +1000,7 @@ static const struct kdc_patypes pat[] = {
{
KRB5_PADATA_GSS , "GSS",
PA_ANNOUNCE | PA_SYNTHETIC_OK | PA_REPLACE_REPLY_KEY,
pa_gss_validate, pa_gss_finalize_pac, pa_gss_cleanup
pa_gss_validate, pa_gss_finalize_pac, NULL
},
};

View File

@@ -16,6 +16,10 @@ EXPORTS
krb5_kdc_save_request
krb5_kdc_update_time
krb5_kdc_pk_initialize
krb5_kdc_request_set_attribute
krb5_kdc_request_get_attribute
krb5_kdc_request_copy_attribute
krb5_kdc_request_delete_attribute
_kdc_audit_addkv
_kdc_audit_addkv_timediff
_kdc_audit_getkv

View File

@@ -359,7 +359,10 @@ process_request(krb5_context context,
r->datagram_reply = datagram_reply;
r->reply = reply;
r->kv = heim_dict_create(10);
if (!r->kv) {
r->attributes = heim_dict_create(1);
if (r->kv == NULL || r->attributes == NULL) {
heim_release(r->kv);
heim_release(r->attributes);
free(r);
return krb5_enomem(context);
}
@@ -385,6 +388,7 @@ process_request(krb5_context context,
heim_release(r->reason);
heim_release(r->kv);
heim_release(r->attributes);
free(r);
return ret;
}
@@ -392,6 +396,7 @@ process_request(krb5_context context,
heim_release(r->reason);
heim_release(r->kv);
heim_release(r->attributes);
free(r);
return -1;
}
@@ -505,3 +510,27 @@ out:
return 0;
}
krb5_error_code
krb5_kdc_request_set_attribute(kdc_request_t r, heim_object_t key, heim_object_t value)
{
return heim_dict_set_value(r->attributes, key, value);
}
heim_object_t
krb5_kdc_request_get_attribute(kdc_request_t r, heim_object_t key)
{
return heim_dict_get_value(r->attributes, key);
}
heim_object_t
krb5_kdc_request_copy_attribute(kdc_request_t r, heim_object_t key)
{
return heim_dict_copy_value(r->attributes, key);
}
void
krb5_kdc_request_delete_attribute(kdc_request_t r, heim_object_t key)
{
heim_dict_delete_key(r->attributes, key);
}

View File

@@ -20,6 +20,10 @@ HEIMDAL_KDC_1.0 {
krb5_kdc_save_request;
krb5_kdc_update_time;
krb5_kdc_pk_initialize;
krb5_kdc_request_set_attribute;
krb5_kdc_request_get_attribute;
krb5_kdc_request_copy_attribute;
krb5_kdc_request_delete_attribute;
_kdc_audit_addkv;
_kdc_audit_setkv_bool;
_kdc_audit_setkv_number;

View File

@@ -72,6 +72,7 @@
heim_string_t reason; \
/* auditing key/value store */ \
heim_dict_t kv; \
heim_dict_t attributes; \
int32_t ret
#endif /* HEIMBASE_SVC_H */

View File

@@ -106,20 +106,48 @@ static krb5_error_code KRB5_CALLCONV
client_access(void *ctx, astgs_request_t r)
{
logit("client_access", r);
return 0;
}
static krb5_error_code KRB5_CALLCONV
finalize_reply(void *ctx, astgs_request_t r)
{
heim_number_t n;
krb5_error_code ret;
logit("finalize_reply", r);
return 0;
n = heim_number_create(1234);
if (n == NULL)
return ENOMEM;
ret = krb5_kdc_request_set_attribute((kdc_request_t)r,
HSTR("org.h5l.tests.kdc-plugin"), n);
heim_release(n);
return ret;
}
static krb5_error_code KRB5_CALLCONV
audit(void *ctx, astgs_request_t r)
{
heim_number_t n;
logit("audit", r);
if (r->ret)
return 0; /* finalize_reply only called in success */
n = krb5_kdc_request_get_attribute((kdc_request_t)r,
HSTR("org.h5l.tests.kdc-plugin"));
heim_assert(n && heim_number_get_int(n) == 1234,
"attribute not passed from finalize_reply");
if (n == NULL || heim_number_get_int(n) != 1234)
return EINVAL; /* return value is ignored, but for completeness */
return 0;
}