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->req_life = 0;
r->ret = 0; r->ret = 0;
r->kv = heim_dict_create(10); r->kv = heim_dict_create(10);
r->attributes = heim_dict_create(1);
ci = MHD_get_connection_info(connection, ci = MHD_get_connection_info(connection,
MHD_CONNECTION_INFO_CLIENT_ADDRESS); MHD_CONNECTION_INFO_CLIENT_ADDRESS);
if (ci) { if (ci) {

View File

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

View File

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

View File

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

View File

@@ -583,13 +583,13 @@ pa_gss_validate(astgs_request_t r, const PA_DATA *pa)
goto out; goto out;
} }
heim_assert(r->pa_state == NULL, "already have PA state, should be NULL"); ret = krb5_kdc_request_set_attribute((kdc_request_t)r,
r->pa_state = (struct as_request_pa_state *)gcp; HSTR("org.h5l.pa-gss-client-params"), gcp);
gcp = NULL; if (ret)
goto out;
out: out:
if (gcp) heim_release(gcp);
_kdc_gss_free_client_param(r, gcp);
free(client_name); free(client_name);
return ret; return ret;
@@ -598,24 +598,15 @@ out:
static krb5_error_code static krb5_error_code
pa_gss_finalize_pac(astgs_request_t r) 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"); heim_assert(gcp != NULL, "invalid GSS-API client params");
return _kdc_gss_finalize_pac(r, gcp); 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 static krb5_error_code
pa_enc_chal_validate(astgs_request_t r, const PA_DATA *pa) 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", KRB5_PADATA_GSS , "GSS",
PA_ANNOUNCE | PA_SYNTHETIC_OK | PA_REPLACE_REPLY_KEY, 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_save_request
krb5_kdc_update_time krb5_kdc_update_time
krb5_kdc_pk_initialize 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
_kdc_audit_addkv_timediff _kdc_audit_addkv_timediff
_kdc_audit_getkv _kdc_audit_getkv

View File

@@ -359,7 +359,10 @@ process_request(krb5_context context,
r->datagram_reply = datagram_reply; r->datagram_reply = datagram_reply;
r->reply = reply; r->reply = reply;
r->kv = heim_dict_create(10); 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); free(r);
return krb5_enomem(context); return krb5_enomem(context);
} }
@@ -385,6 +388,7 @@ process_request(krb5_context context,
heim_release(r->reason); heim_release(r->reason);
heim_release(r->kv); heim_release(r->kv);
heim_release(r->attributes);
free(r); free(r);
return ret; return ret;
} }
@@ -392,6 +396,7 @@ process_request(krb5_context context,
heim_release(r->reason); heim_release(r->reason);
heim_release(r->kv); heim_release(r->kv);
heim_release(r->attributes);
free(r); free(r);
return -1; return -1;
} }
@@ -505,3 +510,27 @@ out:
return 0; 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_save_request;
krb5_kdc_update_time; krb5_kdc_update_time;
krb5_kdc_pk_initialize; 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;
_kdc_audit_setkv_bool; _kdc_audit_setkv_bool;
_kdc_audit_setkv_number; _kdc_audit_setkv_number;

View File

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

View File

@@ -106,20 +106,48 @@ static krb5_error_code KRB5_CALLCONV
client_access(void *ctx, astgs_request_t r) client_access(void *ctx, astgs_request_t r)
{ {
logit("client_access", r); logit("client_access", r);
return 0; return 0;
} }
static krb5_error_code KRB5_CALLCONV static krb5_error_code KRB5_CALLCONV
finalize_reply(void *ctx, astgs_request_t r) finalize_reply(void *ctx, astgs_request_t r)
{ {
heim_number_t n;
krb5_error_code ret;
logit("finalize_reply", r); 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 static krb5_error_code KRB5_CALLCONV
audit(void *ctx, astgs_request_t r) audit(void *ctx, astgs_request_t r)
{ {
heim_number_t n;
logit("audit", r); 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; return 0;
} }