Example #1
0
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;
}