aboutsummaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorGreg Hudson <ghudson@mit.edu>2009-11-14 04:46:30 +0000
committerGreg Hudson <ghudson@mit.edu>2009-11-14 04:46:30 +0000
commit0524889196c42d81dcc4c74277522b46f987cabb (patch)
tree9f906eb1a4a32346ae94837c4fe199410e2dd10f /src/lib
parent26044e2a3c3104b9c3f32a6ae58145e7e6394672 (diff)
downloadkrb5-0524889196c42d81dcc4c74277522b46f987cabb.zip
krb5-0524889196c42d81dcc4c74277522b46f987cabb.tar.gz
krb5-0524889196c42d81dcc4c74277522b46f987cabb.tar.bz2
Constrained delegation without PAC support
Merge Luke's users/lhoward/s4u2proxy branch to trunk. Implements a Heimdal-compatible mechanism for allowing constrained delegation without back-end support for PACs. Back-end support exists in LDAP only (via a new krbAllowedToDelegateTo attribute), not DB2. ticket: 6580 git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@23160 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/krb5/asn.1/asn1_k_decode.c84
-rw-r--r--src/lib/krb5/asn.1/asn1_k_decode.h6
-rw-r--r--src/lib/krb5/asn.1/asn1_k_encode.c55
-rw-r--r--src/lib/krb5/asn.1/krb5_decode.c36
-rw-r--r--src/lib/krb5/krb/copy_auth.c61
-rw-r--r--src/lib/krb5/krb/kfree.c17
-rw-r--r--src/lib/krb5/libkrb5.exports5
7 files changed, 243 insertions, 21 deletions
diff --git a/src/lib/krb5/asn.1/asn1_k_decode.c b/src/lib/krb5/asn.1/asn1_k_decode.c
index 7653990..dd1a2ae 100644
--- a/src/lib/krb5/asn.1/asn1_k_decode.c
+++ b/src/lib/krb5/asn.1/asn1_k_decode.c
@@ -1007,6 +1007,45 @@ error_out:
return retval;
}
+static asn1_error_code asn1_peek_authdata_elt(asn1buf *buf, krb5_authdatatype *val)
+{
+ setup();
+ *val = 0;
+ { begin_structure();
+ get_field(*val, 0, asn1_decode_authdatatype);
+ end_structure();
+ }
+ return 0;
+error_out:
+ return retval;
+}
+
+asn1_error_code asn1_peek_authorization_data
+(asn1buf *buf, unsigned int *num, krb5_authdatatype **val)
+{
+ int size = 0;
+ krb5_authdatatype *array = NULL, *new_array;
+
+ asn1_error_code retval;
+ { sequence_of(buf);
+ while (asn1buf_remains(&seqbuf,seqofindef) > 0) {
+ size++;
+ new_array = realloc(array,size*sizeof(krb5_authdatatype));
+ if (new_array == NULL) clean_return(ENOMEM);
+ array = new_array;
+ retval = asn1_peek_authdata_elt(&seqbuf,&array[size-1]);
+ if (retval) clean_return(retval);
+ }
+ end_sequence_of(buf);
+ }
+ *num = size;
+ *val = array;
+ return 0;
+error_out:
+ free(array);
+ return retval;
+}
+
asn1_error_code
asn1_decode_authdata_elt_ptr(asn1buf *buf, krb5_authdata **valptr)
{
@@ -1812,6 +1851,51 @@ error_out:
return retval;
}
+static asn1_error_code asn1_decode_princ_plus_realm
+(asn1buf *buf, krb5_principal *valptr)
+{
+ setup();
+ alloc_principal((*valptr));
+ { begin_structure();
+ get_field((*valptr), 0, asn1_decode_principal_name);
+ get_field((*valptr), 1, asn1_decode_realm);
+ end_structure();
+ }
+ return 0;
+error_out:
+ krb5_free_principal(NULL, *valptr);
+ *valptr = NULL;
+ return retval;
+}
+
+static asn1_error_code asn1_decode_sequence_of_princ_plus_realm
+(asn1buf *buf, krb5_principal **val)
+{
+ decode_array_body(krb5_principal_data,asn1_decode_princ_plus_realm,krb5_free_principal);
+}
+
+asn1_error_code asn1_decode_ad_signedpath
+(asn1buf *buf, krb5_ad_signedpath *val)
+{
+ setup();
+ val->enctype = ENCTYPE_NULL;
+ val->checksum.contents = NULL;
+ val->delegated = NULL;
+ {
+ begin_structure();
+ get_field(val->enctype, 0, asn1_decode_enctype);
+ get_field(val->checksum, 1, asn1_decode_checksum);
+ opt_field(val->delegated, 2, asn1_decode_sequence_of_princ_plus_realm,
+ NULL);
+ opt_field(val->method_data, 3, asn1_decode_sequence_of_pa_data, NULL);
+ end_structure();
+ }
+ return 0;
+error_out:
+ krb5_free_checksum_contents(NULL, &val->checksum);
+ return retval;
+}
+
#ifndef DISABLE_PKINIT
/* PKINIT */
diff --git a/src/lib/krb5/asn.1/asn1_k_decode.h b/src/lib/krb5/asn.1/asn1_k_decode.h
index 8041535..1b0aa75 100644
--- a/src/lib/krb5/asn.1/asn1_k_decode.h
+++ b/src/lib/krb5/asn.1/asn1_k_decode.h
@@ -134,6 +134,9 @@ asn1_error_code asn1_decode_last_req_entry_ptr(asn1buf *buf,
asn1_error_code asn1_decode_authdata_elt(asn1buf *buf, krb5_authdata *val);
asn1_error_code asn1_decode_authdata_elt_ptr(asn1buf *buf,
krb5_authdata **valptr);
+asn1_error_code asn1_peek_authorization_data(asn1buf *buf,
+ unsigned int *num,
+ krb5_authdatatype **val);
asn1_error_code asn1_decode_krb_cred_info(asn1buf *buf, krb5_cred_info *val);
asn1_error_code asn1_decode_krb_cred_info_ptr(asn1buf *buf,
krb5_cred_info **valptr);
@@ -265,4 +268,7 @@ asn1_error_code asn1_decode_ad_kdcissued(asn1buf *buf, krb5_ad_kdcissued *val);
asn1_error_code asn1_decode_ad_kdcissued_ptr(asn1buf *buf,
krb5_ad_kdcissued **val);
+asn1_error_code asn1_decode_ad_signedpath(asn1buf *buf,
+ krb5_ad_signedpath *val);
+
#endif
diff --git a/src/lib/krb5/asn.1/asn1_k_encode.c b/src/lib/krb5/asn.1/asn1_k_encode.c
index d0371f5..22ebae3 100644
--- a/src/lib/krb5/asn.1/asn1_k_encode.c
+++ b/src/lib/krb5/asn.1/asn1_k_encode.c
@@ -97,7 +97,6 @@ DEFFIELDTYPE(realm_of_principal_data, krb5_principal_data,
FIELDOF_NORM(krb5_principal_data, gstring_data, realm, -1));
DEFPTRTYPE(realm_of_principal, realm_of_principal_data);
-
static const struct field_info princname_fields[] = {
FIELDOF_NORM(krb5_principal_data, int32, type, 0),
FIELDOF_SEQOF_INT32(krb5_principal_data, gstring_data_ptr, data, length, 1),
@@ -1331,7 +1330,59 @@ ad_kdcissued_optional(const void *p)
DEFSEQTYPE(ad_kdc_issued, krb5_ad_kdcissued, ad_kdcissued_fields, ad_kdcissued_optional);
+static const struct field_info princ_plus_realm_fields[] = {
+ FIELDOF_ENCODEAS(krb5_principal_data, principal_data, 0),
+ FIELDOF_ENCODEAS(krb5_principal_data, realm_of_principal_data, 1),
+};
+
+DEFSEQTYPE(princ_plus_realm_data, krb5_principal_data, princ_plus_realm_fields, 0);
+DEFPTRTYPE(princ_plus_realm, princ_plus_realm_data);
+
+DEFNULLTERMSEQOFTYPE(seq_of_princ_plus_realm, princ_plus_realm);
+DEFPTRTYPE(ptr_seq_of_princ_plus_realm, seq_of_princ_plus_realm);
+
+static const struct field_info ad_signedpath_data_fields[] = {
+ FIELDOF_NORM(krb5_ad_signedpath_data, princ_plus_realm, client, 0),
+ FIELDOF_NORM(krb5_ad_signedpath_data, kerberos_time, authtime, 1),
+ FIELDOF_OPT(krb5_ad_signedpath_data, ptr_seq_of_princ_plus_realm, delegated, 2, 2),
+ FIELDOF_OPT(krb5_ad_signedpath_data, ptr_seqof_pa_data, method_data, 3, 3),
+ FIELDOF_OPT(krb5_ad_signedpath_data, auth_data_ptr, authorization_data, 4, 4),
+};
+
+static unsigned int ad_signedpath_data_optional(const void *p)
+{
+ unsigned int optional = 0;
+ const krb5_ad_signedpath_data *val = p;
+ if (val->delegated && val->delegated[0])
+ optional |= (1u << 2);
+ if (val->method_data && val->method_data[0])
+ optional |= (1u << 3);
+ if (val->authorization_data && val->authorization_data[0])
+ optional |= (1u << 4);
+ return optional;
+}
+
+DEFSEQTYPE(ad_signedpath_data, krb5_ad_signedpath_data, ad_signedpath_data_fields, ad_signedpath_data_optional);
+
+static const struct field_info ad_signedpath_fields[] = {
+ FIELDOF_NORM(krb5_ad_signedpath, int32, enctype, 0),
+ FIELDOF_NORM(krb5_ad_signedpath, checksum, checksum, 1),
+ FIELDOF_OPT(krb5_ad_signedpath, ptr_seq_of_princ_plus_realm, delegated, 2, 2),
+ FIELDOF_OPT(krb5_ad_signedpath, ptr_seqof_pa_data, method_data, 3, 3),
+};
+
+static unsigned int ad_signedpath_optional(const void *p)
+{
+ unsigned int optional = 0;
+ const krb5_ad_signedpath *val = p;
+ if (val->delegated && val->delegated[0])
+ optional |= (1u << 2);
+ if (val->method_data && val->method_data[0])
+ optional |= (1u << 3);
+ return optional;
+}
+DEFSEQTYPE(ad_signedpath, krb5_ad_signedpath, ad_signedpath_fields, ad_signedpath_optional);
/* Exported complete encoders -- these produce a krb5_data with
the encoding in the correct byte order. */
@@ -1407,6 +1458,8 @@ MAKE_FULL_ENCODER( encode_krb5_pa_fx_fast_reply, pa_fx_fast_reply);
MAKE_FULL_ENCODER(encode_krb5_fast_response, fast_response);
MAKE_FULL_ENCODER(encode_krb5_ad_kdcissued, ad_kdc_issued);
+MAKE_FULL_ENCODER(encode_krb5_ad_signedpath_data, ad_signedpath_data);
+MAKE_FULL_ENCODER(encode_krb5_ad_signedpath, ad_signedpath);
diff --git a/src/lib/krb5/asn.1/krb5_decode.c b/src/lib/krb5/asn.1/krb5_decode.c
index fa835fe..0daa32e 100644
--- a/src/lib/krb5/asn.1/krb5_decode.c
+++ b/src/lib/krb5/asn.1/krb5_decode.c
@@ -1192,6 +1192,42 @@ krb5_error_code decode_krb5_ad_kdcissued
cleanup(free);
}
+krb5_error_code decode_krb5_ad_signedpath
+(const krb5_data *code, krb5_ad_signedpath **repptr)
+{
+ setup_buf_only(krb5_ad_signedpath *);
+ alloc_field(rep);
+
+ retval = asn1_decode_ad_signedpath(&buf, rep);
+ if (retval) clean_return(retval);
+
+ cleanup(free);
+}
+
+krb5_error_code
+krb5int_get_authdata_containee_types(krb5_context context,
+ const krb5_authdata *authdata,
+ unsigned int *num,
+ krb5_authdatatype **repptr)
+{
+ krb5_data data, *code = &data;
+
+ data.data = (char *)authdata->contents;
+ data.length = authdata->length;
+
+ *num = 0;
+
+ {
+ setup_buf_only(krb5_authdatatype *);
+
+ retval = asn1_peek_authorization_data(&buf, num, &rep);
+ if (retval) clean_return(retval);
+
+ cleanup_none();
+ }
+ assert(0); /* NOTREACHED */
+}
+
#ifndef DISABLE_PKINIT
krb5_error_code
decode_krb5_pa_pk_as_req(const krb5_data *code, krb5_pa_pk_as_req **repptr)
diff --git a/src/lib/krb5/krb/copy_auth.c b/src/lib/krb5/krb/copy_auth.c
index 0262fe5..d4c2700 100644
--- a/src/lib/krb5/krb/copy_auth.c
+++ b/src/lib/krb5/krb/copy_auth.c
@@ -223,34 +223,47 @@ grow_find_authdata(krb5_context context, struct find_authdata_context *fctx,
static krb5_error_code
find_authdata_1(krb5_context context, krb5_authdata *const *in_authdat,
- krb5_authdatatype ad_type, struct find_authdata_context *fctx)
+ krb5_authdatatype ad_type, struct find_authdata_context *fctx,
+ int from_ap_req)
{
int i = 0;
- krb5_error_code retval=0;
+ krb5_error_code retval = 0;
for (i = 0; in_authdat[i]; i++) {
krb5_authdata *ad = in_authdat[i];
- if (ad->ad_type == ad_type && retval ==0)
- retval = grow_find_authdata(context, fctx, ad);
- else switch (ad->ad_type) {
- krb5_authdata **decoded_container;
- case KRB5_AUTHDATA_IF_RELEVANT:
- if (retval == 0)
- retval = krb5_decode_authdata_container( context, ad->ad_type, ad, &decoded_container);
- if (retval == 0) {
- retval = find_authdata_1(context,
- decoded_container, ad_type, fctx);
- krb5_free_authdata(context, decoded_container);
- }
- break;
- default:
- break;
+ krb5_authdata **decoded_container;
+
+ switch (ad->ad_type) {
+ case KRB5_AUTHDATA_IF_RELEVANT:
+ if (retval == 0)
+ retval = krb5_decode_authdata_container(context,
+ ad->ad_type,
+ ad,
+ &decoded_container);
+ if (retval == 0) {
+ retval = find_authdata_1(context,
+ decoded_container,
+ ad_type,
+ fctx,
+ from_ap_req);
+ krb5_free_authdata(context, decoded_container);
}
+ break;
+ case KRB5_AUTHDATA_SIGNTICKET:
+ case KRB5_AUTHDATA_KDC_ISSUED:
+ case KRB5_AUTHDATA_WIN2K_PAC:
+ if (from_ap_req)
+ continue;
+ default:
+ if (ad->ad_type == ad_type && retval == 0)
+ retval = grow_find_authdata(context, fctx, ad);
+ break;
+ }
}
+
return retval;
}
-
krb5_error_code
krb5int_find_authdata(krb5_context context,
krb5_authdata *const *ticket_authdata,
@@ -266,9 +279,9 @@ krb5int_find_authdata(krb5_context context,
if (fctx.out == NULL)
return ENOMEM;
if (ticket_authdata)
- retval = find_authdata_1( context, ticket_authdata, ad_type, &fctx);
+ retval = find_authdata_1( context, ticket_authdata, ad_type, &fctx, 0);
if ((retval==0) && ap_req_authdata)
- retval = find_authdata_1( context, ap_req_authdata, ad_type, &fctx);
+ retval = find_authdata_1( context, ap_req_authdata, ad_type, &fctx, 1);
if ((retval== 0) && fctx.length)
*results = fctx.out;
else krb5_free_authdata(context, fctx.out);
@@ -300,6 +313,9 @@ krb5_make_authdata_kdc_issued(krb5_context context,
if (code != 0)
return code;
+ if (!krb5_c_is_keyed_cksum(cksumtype))
+ return KRB5KRB_AP_ERR_INAPP_CKSUM;
+
code = encode_krb5_authdata(ad_kdci.elements, &data);
if (code != 0)
return code;
@@ -361,6 +377,11 @@ krb5_verify_authdata_kdc_issued(krb5_context context,
if (code != 0)
return code;
+ if (!krb5_c_is_keyed_cksum(ad_kdci->ad_checksum.checksum_type)) {
+ krb5_free_ad_kdcissued(context, ad_kdci);
+ return KRB5KRB_AP_ERR_INAPP_CKSUM;
+ }
+
code = encode_krb5_authdata(ad_kdci->elements, &data2);
if (code != 0) {
krb5_free_ad_kdcissued(context, ad_kdci);
diff --git a/src/lib/krb5/krb/kfree.c b/src/lib/krb5/krb/kfree.c
index c372e70..02906a1 100644
--- a/src/lib/krb5/krb/kfree.c
+++ b/src/lib/krb5/krb/kfree.c
@@ -909,3 +909,20 @@ krb5_free_ad_kdcissued(krb5_context context, krb5_ad_kdcissued *val)
krb5_free_authdata(context, val->elements);
free(val);
}
+
+void KRB5_CALLCONV
+krb5_free_ad_signedpath(krb5_context context, krb5_ad_signedpath *val)
+{
+ int i;
+
+ if (val == NULL)
+ return;
+
+ krb5_free_checksum_contents(context, &val->checksum);
+ if (val->delegated != NULL) {
+ for (i = 0; val->delegated[i] != NULL; i++)
+ krb5_free_principal(context, val->delegated[i]);
+ free(val->delegated);
+ }
+ krb5_free_pa_data(context, val->method_data);
+}
diff --git a/src/lib/krb5/libkrb5.exports b/src/lib/krb5/libkrb5.exports
index 2735c9f..8ef3a9d 100644
--- a/src/lib/krb5/libkrb5.exports
+++ b/src/lib/krb5/libkrb5.exports
@@ -1,5 +1,6 @@
_krb5_conf_boolean
decode_krb5_ad_kdcissued
+decode_krb5_ad_signedpath
decode_krb5_alt_method
decode_krb5_ap_rep
decode_krb5_ap_rep_enc_part
@@ -42,6 +43,8 @@ decode_krb5_tgs_req
decode_krb5_ticket
decode_krb5_typed_data
encode_krb5_ad_kdcissued
+encode_krb5_ad_signedpath_data
+encode_krb5_ad_signedpath
encode_krb5_alt_method
encode_krb5_ap_rep
encode_krb5_ap_rep_enc_part
@@ -220,6 +223,7 @@ krb5_externalize_opaque
krb5_fcc_ops
krb5_find_serializer
krb5_free_ad_kdcissued
+krb5_free_ad_signedpath
krb5_free_address
krb5_free_addresses
krb5_free_alt_method
@@ -554,6 +558,7 @@ krb5int_find_pa_data
krb5int_foreach_localaddr
krb5int_free_addrlist
krb5int_free_data_list
+krb5int_get_authdata_containee_types
krb5int_get_domain_realm_mapping
krb5int_init_context_kdc
krb5int_initialize_library