コード例 #1
0
ファイル: preauth_otp.c プロジェクト: Akasurde/krb5
/*
 * Try to find tokeninfos which match configuration data recorded in the input
 * ccache, and if exactly one is found, drop the rest.
 */
static krb5_error_code
filter_config_tokeninfos(krb5_context context,
                         krb5_clpreauth_callbacks cb,
                         krb5_clpreauth_rock rock,
                         krb5_otp_tokeninfo **tis)
{
    krb5_otp_tokeninfo *match = NULL;
    size_t i, j;
    const char *vendor, *alg_id, *token_id;

    /* Pull up what we know about the token we want to use. */
    vendor = cb->get_cc_config(context, rock, "vendor");
    alg_id = cb->get_cc_config(context, rock, "algID");
    token_id = cb->get_cc_config(context, rock, "tokenID");

    /* Look for a single matching entry. */
    for (i = 0; tis[i] != NULL; i++) {
        if (vendor != NULL && tis[i]->vendor.length > 0 &&
            !data_eq_string(tis[i]->vendor, vendor))
            continue;
        if (alg_id != NULL && tis[i]->alg_id.length > 0 &&
            !data_eq_string(tis[i]->alg_id, alg_id))
            continue;
        if (token_id != NULL && tis[i]->token_id.length > 0 &&
            !data_eq_string(tis[i]->token_id, token_id))
            continue;
        /* Oh, we already had a matching entry. More than one -> no change. */
        if (match != NULL)
            return 0;
        match = tis[i];
    }

    /* No matching entry -> no change. */
    if (match == NULL)
        return 0;

    /* Prune out everything except the best match. */
    for (i = 0, j = 0; tis[i] != NULL; i++) {
        if (tis[i] != match)
            k5_free_otp_tokeninfo(context, tis[i]);
        else
            tis[j++] = tis[i];
    }
    tis[j] = NULL;

    return 0;
}