}
if (s->warn_hk) {
+ int j, k;
+ char *betteralgs;
+
ssh_set_frozen(ssh, 1);
- s->dlgret = askalg(ssh->frontend, "host key type",
- ssh->hostkey->name,
- ssh_dialog_callback, ssh);
+
+ /*
+ * Change warning box wording depending on why we chose a
+ * warning-level host key algorithm. If it's because
+ * that's all we have *cached*, use the askhk mechanism,
+ * and list the host keys we could usefully cross-certify.
+ * Otherwise, use askalg for the standard wording.
+ */
+ betteralgs = NULL;
+ for (j = 0; j < ssh->n_uncert_hostkeys; j++) {
+ const struct ssh_signkey_with_user_pref_id *hktype =
+ &hostkey_algs[ssh->uncert_hostkeys[j]];
+ int better = FALSE;
+ for (k = 0; k < HK_MAX; k++) {
+ int id = conf_get_int_int(ssh->conf, CONF_ssh_hklist, k);
+ if (id == HK_WARN) {
+ break;
+ } else if (id == hktype->id) {
+ better = TRUE;
+ break;
+ }
+ }
+ if (better) {
+ if (betteralgs) {
+ char *old_ba = betteralgs;
+ betteralgs = dupcat(betteralgs, ",",
+ hktype->alg->name,
+ (const char *)NULL);
+ sfree(old_ba);
+ } else {
+ betteralgs = dupstr(hktype->alg->name);
+ }
+ }
+ }
+ if (betteralgs) {
+ s->dlgret = askhk(ssh->frontend, ssh->hostkey->name,
+ betteralgs, ssh_dialog_callback, ssh);
+ sfree(betteralgs);
+ } else {
+ s->dlgret = askalg(ssh->frontend, "host key type",
+ ssh->hostkey->name,
+ ssh_dialog_callback, ssh);
+ }
if (s->dlgret < 0) {
do {
crReturnV;
s->keystr = ssh->hostkey->fmtkey(s->hkey);
if (!s->got_session_id) {
/*
- * Make a note of any host key format we'd have preferred to use,
- * had we already known the corresponding keys.
+ * Make a note of any other host key formats that are available.
*/
{
- int i, j = 0;
+ int i, j;
char *list = NULL;
for (i = 0; i < lenof(hostkey_algs); i++) {
if (hostkey_algs[i].alg == ssh->hostkey)
- /* Not worth mentioning key types we wouldn't use */
- break;
- else if (ssh->uncert_hostkeys[j] == i) {
+ continue;
+
+ for (j = 0; j < ssh->n_uncert_hostkeys; j++)
+ if (ssh->uncert_hostkeys[j] == i)
+ break;
+
+ if (j < ssh->n_uncert_hostkeys) {
char *newlist;
if (list)
newlist = dupprintf("%s/%s", list,
newlist = dupprintf("%s", hostkey_algs[i].alg->name);
sfree(list);
list = newlist;
- j++;
- /* Assumes that hostkey_algs and uncert_hostkeys are
- * sorted in the same order */
- if (j == ssh->n_uncert_hostkeys)
- break;
- else
- assert(ssh->uncert_hostkeys[j] >
- ssh->uncert_hostkeys[j-1]);
}
}
if (list) {
logeventf(ssh,
- "Server has %s host key%s, but we don't know %s; "
- "using %s instead",
- list, j ? "s" : "", j ? "any of them" : "it",
- ssh->hostkey->name);
+ "Server also has %s host key%s, but we "
+ "don't know %s", list,
+ j > 1 ? "s" : "", j > 1 ? "any of them" : "it");
sfree(list);
}
}