return code;
}
+/* Decode and verify each CAMMAC and collect the resulting authdata,
+ * ignoring those that failed verification. */
+static krb5_error_code
+extract_cammacs(krb5_context kcontext, krb5_authdata **cammacs,
+ const krb5_keyblock *key, krb5_authdata ***ad_out)
+{
+ krb5_error_code ret;
+ krb5_authdata **list = NULL, **elements = NULL, **new_list;
+ size_t i, n_elements, count = 0;
+
+ *ad_out = NULL;
+
+ for (i = 0; cammacs != NULL && cammacs[i] != NULL; i++) {
+ ret = k5_unwrap_cammac_svc(kcontext, cammacs[i], key, &elements);
+ if (ret && ret != KRB5KRB_AP_ERR_BAD_INTEGRITY)
+ goto cleanup;
+ ret = 0;
+
+ /* Add the verified elements to list and free the container array. */
+ for (n_elements = 0; elements[n_elements] != NULL; n_elements++);
+ new_list = realloc(list, (count + n_elements + 1) * sizeof(list));
+ if (new_list == NULL) {
+ ret = ENOMEM;
+ goto cleanup;
+ }
+ list = new_list;
+ memcpy(list + count, elements, n_elements * sizeof(list));
+ count += n_elements;
+ list[count] = NULL;
+ free(elements);
+ elements = NULL;
+ }
+
+ *ad_out = list;
+ list = NULL;
+
+cleanup:
+ krb5_free_authdata(kcontext, list);
+ krb5_free_authdata(kcontext, elements);
+ return ret;
+}
+
+/* Retrieve verified CAMMAC contained elements. */
+static krb5_error_code
+get_cammac_authdata(krb5_context kcontext, const krb5_ap_req *ap_req,
+ const krb5_keyblock *key, krb5_authdata ***elems_out)
+{
+ krb5_error_code ret = 0;
+ krb5_authdata **ticket_authdata, **cammacs, **elements;
+
+ *elems_out = NULL;
+
+ ticket_authdata = ap_req->ticket->enc_part2->authorization_data;
+ ret = krb5_find_authdata(kcontext, ticket_authdata, NULL,
+ KRB5_AUTHDATA_CAMMAC, &cammacs);
+ if (ret || cammacs == NULL)
+ return ret;
+
+ ret = extract_cammacs(kcontext, cammacs, key, &elements);
+ if (!ret)
+ *elems_out = elements;
+
+ krb5_free_authdata(kcontext, cammacs);
+ return ret;
+}
+
krb5_error_code
krb5int_authdata_verify(krb5_context kcontext,
krb5_authdata_context context,
krb5_authdata **ticket_authdata;
krb5_principal kdc_issuer = NULL;
krb5_authdata **kdc_issued_authdata = NULL;
+ krb5_authdata **cammac_authdata = NULL;
authen_authdata = (*auth_context)->authentp->authorization_data;
ticket_authdata = ap_req->ticket->enc_part2->authorization_data;
k5_get_kdc_issued_authdata(kcontext, ap_req,
&kdc_issuer, &kdc_issued_authdata);
+ code = get_cammac_authdata(kcontext, ap_req, key, &cammac_authdata);
+ if (code)
+ goto cleanup;
+
for (i = 0; i < context->n_modules; i++) {
struct _krb5_authdata_context_module *module = &context->modules[i];
krb5_authdata **authdata = NULL;
kdc_issued_flag = TRUE;
}
+ if (cammac_authdata != NULL && (module->flags & AD_CAMMAC_PROTECTED)) {
+ authdata = cammac_authdata;
+ kdc_issued_flag = TRUE;
+ }
+
if (authdata == NULL) {
krb5_boolean ticket_usage = FALSE;
krb5_boolean authen_usage = FALSE;
break;
}
+cleanup:
krb5_free_principal(kcontext, kdc_issuer);
krb5_free_authdata(kcontext, kdc_issued_authdata);