void k5_free_pa_otp_challenge(krb5_context context, krb5_pa_otp_challenge *val) { krb5_otp_tokeninfo **ti; if (val == NULL) return; free(val->nonce.data); free(val->service.data); for (ti = val->tokeninfo; *ti != NULL; ti++) k5_free_otp_tokeninfo(context, *ti); free(val->tokeninfo); free(val->salt.data); free(val->s2kparams.data); free(val); }
/* * 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; }
/* Removes unsupported tokeninfos. Returns an error if no tokeninfos remain. */ static krb5_error_code filter_supported_tokeninfos(krb5_context context, krb5_otp_tokeninfo **tis) { size_t i, j; /* Filter out any tokeninfos we don't support. */ for (i = 0, j = 0; tis[i] != NULL; i++) { if (!is_tokeninfo_supported(tis[i])) k5_free_otp_tokeninfo(context, tis[i]); else tis[j++] = tis[i]; } /* Terminate the array. */ tis[j] = NULL; if (tis[0] != NULL) return 0; k5_setmsg(context, KRB5_PREAUTH_FAILED, _("No supported tokens")); return KRB5_PREAUTH_FAILED; /* We have no supported tokeninfos. */ }