/* Anything greater or equal to "1.99" means protocol 2 is supported. */
s->proto2 = ssh_versioncmp(s->version, "1.99") >= 0;
- if (conf_get_int(ssh->conf, CONF_sshprot) == 0 && !s->proto1) {
- bombout(("SSH protocol version 1 required by configuration but "
- "not provided by server"));
- crStop(0);
- }
- if (conf_get_int(ssh->conf, CONF_sshprot) == 3 && !s->proto2) {
- bombout(("SSH protocol version 2 required by configuration but "
- "not provided by server"));
- crStop(0);
+ if (conf_get_int(ssh->conf, CONF_sshprot) == 0) {
+ if (!s->proto1) {
+ bombout(("SSH protocol version 1 required by our configuration "
+ "but not provided by server"));
+ crStop(0);
+ }
+ } else if (conf_get_int(ssh->conf, CONF_sshprot) == 3) {
+ if (!s->proto2) {
+ bombout(("SSH protocol version 2 required by our configuration "
+ "but server only provides (old, insecure) SSH-1"));
+ crStop(0);
+ }
+ } else {
+ /* No longer support values 1 or 2 for CONF_sshprot */
+ assert(!"Unexpected value for CONF_sshprot");
}
if (s->proto2 && (conf_get_int(ssh->conf, CONF_sshprot) >= 2 || !s->proto1))
}
/*
- * If the SSH version number's fixed, set it now, and if it's SSH-2,
- * send the version string too.
+ * The SSH version number is always fixed (since we no longer support
+ * fallback between versions), so set it now, and if it's SSH-2,
+ * send the version string now too.
*/
sshprot = conf_get_int(ssh->conf, CONF_sshprot);
+ assert(sshprot == 0 || sshprot == 3);
if (sshprot == 0)
+ /* SSH-1 only */
ssh->version = 1;
if (sshprot == 3 && !ssh->bare_connection) {
+ /* SSH-2 only */
ssh->version = 2;
ssh_send_verstring(ssh, "SSH-", NULL);
}
}
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;
* 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)
continue;
- else if (ssh->uncert_hostkeys[j] == i) {
+
+ 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) {