static GFile * next_match_recurse (Enumerator *e, gint depth) { GFile *file; GFileInfo *info; const gchar *name; while (TRUE) { if (e->enumerators[depth] == NULL) { if (depth > 0) { file = next_match_recurse (e, depth - 1); if (file) { e->children[depth] = file; e->enumerators[depth] = g_file_enumerate_children (file, G_FILE_ATTRIBUTE_STANDARD_NAME, G_FILE_QUERY_INFO_NONE, NULL, NULL); } } if (e->enumerators[depth] == NULL) return NULL; } while ((info = g_file_enumerator_next_file (e->enumerators[depth], NULL, NULL))) { name = g_file_info_get_name (info); if (component_match (e, depth, name)) { file = g_file_get_child (e->children[depth], name); g_object_unref (info); return file; } g_object_unref (info); } g_object_unref (e->enumerators[depth]); e->enumerators[depth] = NULL; g_object_unref (e->children[depth]); e->children[depth] = NULL; } }
/* * Returns match_found == 1 only if exactly one certificate matches * the given rule */ static krb5_error_code check_all_certs(krb5_context context, pkinit_plg_crypto_context plg_cryptoctx, pkinit_req_crypto_context req_cryptoctx, pkinit_identity_crypto_context id_cryptoctx, krb5_principal princ, rule_set *rs, /* rule to check */ pkinit_cert_matching_data **matchdata, int *match_found, pkinit_cert_matching_data **matching_cert) { krb5_error_code retval; pkinit_cert_matching_data *md; int i; int comp_match = 0; int total_cert_matches = 0; rule_component *rc; int certs_checked = 0; pkinit_cert_matching_data *save_match = NULL; char *princ_string = NULL; char *princ_realm = NULL; if (match_found == NULL || matching_cert == NULL) return EINVAL; *matching_cert = NULL; *match_found = 0; pkiDebug("%s: matching rule relation is %s with %d components\n", __FUNCTION__, relation2string(rs->relation), rs->num_crs); if (princ) { retval = krb5_unparse_name(context, princ, &princ_string); if (retval || princ_string == NULL) { return EINVAL; } princ_realm = strchr(princ_string, '@'); if (princ_realm == NULL) { krb5_free_unparsed_name(context, princ_string); return EINVAL; } *princ_realm++ = '\0'; } /* * Loop through all the certs available and count * how many match the rule */ for (i = 0, md = matchdata[i]; md != NULL; md = matchdata[++i]) { pkiDebug("%s: subject: '%s'\n", __FUNCTION__, md->subject_dn); pkiDebug("%s: issuer: '%s'\n", __FUNCTION__, md->issuer_dn); certs_checked++; for (rc = rs->crs; rc != NULL; rc = rc->next) { comp_match = component_match(context, rc, md, princ); if (comp_match) { pkiDebug("%s: match for keyword type %s\n", __FUNCTION__, keyword2string(rc->kw_type)); } if (comp_match && rs->relation == relation_or) { pkiDebug("%s: cert matches rule (OR relation)\n", __FUNCTION__); total_cert_matches++; save_match = md; goto nextcert; } if (!comp_match && rs->relation == relation_and) { pkiDebug("%s: cert does not match rule (AND relation)\n", __FUNCTION__); goto nextcert; } } if (rc == NULL && comp_match) { pkiDebug("%s: cert matches rule (AND relation)\n", __FUNCTION__); total_cert_matches++; save_match = md; } nextcert: continue; } if (princ_string) { krb5_free_unparsed_name(context, princ_string); } pkiDebug("%s: After checking %d certs, we found %d matches\n", __FUNCTION__, certs_checked, total_cert_matches); if (total_cert_matches == 1) { *match_found = 1; *matching_cert = save_match; } retval = 0; pkiDebug("%s: returning %d, match_found %d\n", __FUNCTION__, retval, *match_found); return retval; }