diff --git a/openssh-6.9p1-show-more-fingerprints.patch b/openssh-6.9p1-show-more-fingerprints.patch new file mode 100644 index 0000000..2c636ab --- /dev/null +++ b/openssh-6.9p1-show-more-fingerprints.patch @@ -0,0 +1,293 @@ +diff -up openssh-6.9p1/clientloop.c.fingerprint openssh-6.9p1/clientloop.c +--- openssh-6.9p1/clientloop.c.fingerprint 2015-08-20 11:10:36.381765519 +0200 ++++ openssh-6.9p1/clientloop.c 2015-08-20 11:10:36.436765380 +0200 +@@ -2206,7 +2206,7 @@ update_known_hosts(struct hostkeys_updat + if (ctx->keys_seen[i] != 2) + continue; + if ((fp = sshkey_fingerprint(ctx->keys[i], +- options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) ++ options.fingerprint_hash[0], SSH_FP_DEFAULT)) == NULL) + fatal("%s: sshkey_fingerprint failed", __func__); + do_log2(loglevel, "Learned new hostkey: %s %s", + sshkey_type(ctx->keys[i]), fp); +@@ -2214,7 +2214,7 @@ update_known_hosts(struct hostkeys_updat + } + for (i = 0; i < ctx->nold; i++) { + if ((fp = sshkey_fingerprint(ctx->old_keys[i], +- options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) ++ options.fingerprint_hash[0], SSH_FP_DEFAULT)) == NULL) + fatal("%s: sshkey_fingerprint failed", __func__); + do_log2(loglevel, "Deprecating obsolete hostkey: %s %s", + sshkey_type(ctx->old_keys[i]), fp); +@@ -2257,7 +2257,7 @@ update_known_hosts(struct hostkeys_updat + (r = hostfile_replace_entries(options.user_hostfiles[0], + ctx->host_str, ctx->ip_str, ctx->keys, ctx->nkeys, + options.hash_known_hosts, 0, +- options.fingerprint_hash)) != 0) ++ options.fingerprint_hash[0])) != 0) + error("%s: hostfile_replace_entries failed: %s", + __func__, ssh_err(r)); + } +@@ -2370,7 +2370,7 @@ client_input_hostkeys(void) + error("%s: parse key: %s", __func__, ssh_err(r)); + goto out; + } +- fp = sshkey_fingerprint(key, options.fingerprint_hash, ++ fp = sshkey_fingerprint(key, options.fingerprint_hash[0], + SSH_FP_DEFAULT); + debug3("%s: received %s key %s", __func__, + sshkey_type(key), fp); +diff -up openssh-6.9p1/readconf.c.fingerprint openssh-6.9p1/readconf.c +--- openssh-6.9p1/readconf.c.fingerprint 2015-08-20 11:10:36.385765509 +0200 ++++ openssh-6.9p1/readconf.c 2015-08-20 11:11:38.216609413 +0200 +@@ -1497,16 +1497,18 @@ parse_int: + goto parse_string; + + case oFingerprintHash: +- intptr = &options->fingerprint_hash; +- arg = strdelim(&s); +- if (!arg || *arg == '\0') +- fatal("%.200s line %d: Missing argument.", +- filename, linenum); +- if ((value = ssh_digest_alg_by_name(arg)) == -1) +- fatal("%.200s line %d: Invalid hash algorithm \"%s\".", +- filename, linenum, arg); +- if (*activep && *intptr == -1) +- *intptr = value; ++ if (*activep && options->num_fingerprint_hash == 0) ++ while ((arg = strdelim(&s)) != NULL && *arg != '\0') { ++ value = ssh_digest_alg_by_name(arg); ++ if (value == -1) ++ fatal("%s line %d: unknown fingerprints algorithm specs: %s.", ++ filename, linenum, arg); ++ if (options->num_fingerprint_hash >= SSH_DIGEST_MAX) ++ fatal("%s line %d: too many fingerprints algorithm specs.", ++ filename, linenum); ++ options->fingerprint_hash[ ++ options->num_fingerprint_hash++] = value; ++ } + break; + + case oUpdateHostkeys: +@@ -1709,7 +1711,7 @@ initialize_options(Options * options) + options->canonicalize_fallback_local = -1; + options->canonicalize_hostname = -1; + options->revoked_host_keys = NULL; +- options->fingerprint_hash = -1; ++ options->num_fingerprint_hash = 0; + options->update_hostkeys = -1; + options->hostbased_key_types = NULL; + } +@@ -1895,8 +1897,10 @@ fill_default_options(Options * options) + options->canonicalize_fallback_local = 1; + if (options->canonicalize_hostname == -1) + options->canonicalize_hostname = SSH_CANONICALISE_NO; +- if (options->fingerprint_hash == -1) +- options->fingerprint_hash = SSH_FP_HASH_DEFAULT; ++ if (options->num_fingerprint_hash == 0) { ++ options->fingerprint_hash[options->num_fingerprint_hash++] = SSH_DIGEST_SHA256; ++ options->fingerprint_hash[options->num_fingerprint_hash++] = SSH_DIGEST_MD5; ++ } + if (options->update_hostkeys == -1) + options->update_hostkeys = 0; + if (options->hostbased_key_types == NULL) +@@ -2227,6 +2231,17 @@ dump_cfg_strarray(OpCodes code, u_int co + } + + static void ++dump_cfg_fmtarray(OpCodes code, u_int count, int *vals) ++{ ++ u_int i; ++ ++ printf("%s", lookup_opcode_name(code)); ++ for (i = 0; i < count; i++) ++ printf(" %s", fmt_intarg(code, vals[i])); ++ printf("\n"); ++} ++ ++static void + dump_cfg_strarray_oneline(OpCodes code, u_int count, char **vals) + { + u_int i; +@@ -2297,7 +2312,6 @@ dump_client_config(Options *o, const cha + dump_cfg_fmtint(oControlMaster, o->control_master); + dump_cfg_fmtint(oEnableSSHKeysign, o->enable_ssh_keysign); + dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure); +- dump_cfg_fmtint(oFingerprintHash, o->fingerprint_hash); + dump_cfg_fmtint(oForwardAgent, o->forward_agent); + dump_cfg_fmtint(oForwardX11, o->forward_x11); + dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted); +@@ -2366,6 +2380,7 @@ dump_client_config(Options *o, const cha + dump_cfg_strarray_oneline(oGlobalKnownHostsFile, o->num_system_hostfiles, o->system_hostfiles); + dump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles); + dump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env); ++ dump_cfg_fmtarray(oFingerprintHash, o->num_fingerprint_hash, o->fingerprint_hash); + + /* Special cases */ + +diff -up openssh-6.9p1/readconf.h.fingerprint openssh-6.9p1/readconf.h +--- openssh-6.9p1/readconf.h.fingerprint 2015-08-20 11:10:36.385765509 +0200 ++++ openssh-6.9p1/readconf.h 2015-08-20 11:10:36.437765377 +0200 +@@ -21,6 +21,7 @@ + #define MAX_SEND_ENV 256 + #define SSH_MAX_HOSTS_FILES 32 + #define MAX_CANON_DOMAINS 32 ++#define MAX_SSH_DIGESTS 32 + #define PATH_MAX_SUN (sizeof((struct sockaddr_un *)0)->sun_path) + + struct allowed_cname { +@@ -151,7 +152,8 @@ typedef struct { + + char *revoked_host_keys; + +- int fingerprint_hash; ++ int num_fingerprint_hash; ++ int fingerprint_hash[MAX_SSH_DIGESTS]; + + int update_hostkeys; /* one of SSH_UPDATE_HOSTKEYS_* */ + +diff -up openssh-6.9p1/ssh_config.5.fingerprint openssh-6.9p1/ssh_config.5 +--- openssh-6.9p1/ssh_config.5.fingerprint 2015-08-20 11:10:36.386765506 +0200 ++++ openssh-6.9p1/ssh_config.5 2015-08-20 11:10:36.437765377 +0200 +@@ -642,13 +642,13 @@ or + The default is + .Dq no . + .It Cm FingerprintHash +-Specifies the hash algorithm used when displaying key fingerprints. ++Specifies the hash algorithms used when displaying key fingerprints. + Valid options are: + .Dq md5 + and + .Dq sha256 . + The default is +-.Dq sha256 . ++.Dq "sha256 md5". + .It Cm ForwardAgent + Specifies whether the connection to the authentication agent (if any) + will be forwarded to the remote machine. +diff -up openssh-6.9p1/sshconnect2.c.fingerprint openssh-6.9p1/sshconnect2.c +--- openssh-6.9p1/sshconnect2.c.fingerprint 2015-08-20 11:10:36.403765463 +0200 ++++ openssh-6.9p1/sshconnect2.c 2015-08-20 11:10:36.437765377 +0200 +@@ -658,7 +658,7 @@ input_userauth_pk_ok(int type, u_int32_t + key->type, pktype); + goto done; + } +- if ((fp = sshkey_fingerprint(key, options.fingerprint_hash, ++ if ((fp = sshkey_fingerprint(key, options.fingerprint_hash[0], + SSH_FP_DEFAULT)) == NULL) + goto done; + debug2("input_userauth_pk_ok: fp %s", fp); +@@ -1135,7 +1135,7 @@ sign_and_send_pubkey(Authctxt *authctxt, + int have_sig = 1; + char *fp; + +- if ((fp = sshkey_fingerprint(id->key, options.fingerprint_hash, ++ if ((fp = sshkey_fingerprint(id->key, options.fingerprint_hash[0], + SSH_FP_DEFAULT)) == NULL) + return 0; + debug3("sign_and_send_pubkey: %s %s", key_type(id->key), fp); +@@ -1750,7 +1750,7 @@ userauth_hostbased(Authctxt *authctxt) + goto out; + } + +- if ((fp = sshkey_fingerprint(private, options.fingerprint_hash, ++ if ((fp = sshkey_fingerprint(private, options.fingerprint_hash[0], + SSH_FP_DEFAULT)) == NULL) { + error("%s: sshkey_fingerprint failed", __func__); + goto out; +diff -up openssh-6.9p1/sshconnect.c.fingerprint openssh-6.9p1/sshconnect.c +--- openssh-6.9p1/sshconnect.c.fingerprint 2015-08-20 11:10:36.401765468 +0200 ++++ openssh-6.9p1/sshconnect.c 2015-08-20 11:10:36.437765377 +0200 +@@ -923,9 +923,9 @@ check_host_key(char *hostname, struct so + "of known hosts.", type, ip); + } else if (options.visual_host_key) { + fp = sshkey_fingerprint(host_key, +- options.fingerprint_hash, SSH_FP_DEFAULT); ++ options.fingerprint_hash[0], SSH_FP_DEFAULT); + ra = sshkey_fingerprint(host_key, +- options.fingerprint_hash, SSH_FP_RANDOMART); ++ options.fingerprint_hash[0], SSH_FP_RANDOMART); + if (fp == NULL || ra == NULL) + fatal("%s: sshkey_fingerprint fail", __func__); + logit("Host key fingerprint is %s\n%s\n", fp, ra); +@@ -967,12 +967,6 @@ check_host_key(char *hostname, struct so + else + snprintf(msg1, sizeof(msg1), "."); + /* The default */ +- fp = sshkey_fingerprint(host_key, +- options.fingerprint_hash, SSH_FP_DEFAULT); +- ra = sshkey_fingerprint(host_key, +- options.fingerprint_hash, SSH_FP_RANDOMART); +- if (fp == NULL || ra == NULL) +- fatal("%s: sshkey_fingerprint fail", __func__); + msg2[0] = '\0'; + if (options.verify_host_key_dns) { + if (matching_host_key_dns) +@@ -986,16 +980,28 @@ check_host_key(char *hostname, struct so + } + snprintf(msg, sizeof(msg), + "The authenticity of host '%.200s (%s)' can't be " +- "established%s\n" +- "%s key fingerprint is %s.%s%s\n%s" ++ "established%s\n", host, ip, msg1); ++ for (i = 0; i < options.num_fingerprint_hash; i++) { ++ fp = sshkey_fingerprint(host_key, ++ options.fingerprint_hash[i], SSH_FP_DEFAULT); ++ ra = sshkey_fingerprint(host_key, ++ options.fingerprint_hash[i], SSH_FP_RANDOMART); ++ if (fp == NULL || ra == NULL) ++ fatal("%s: sshkey_fingerprint fail", __func__); ++ len = strlen(msg); ++ snprintf(msg+len, sizeof(msg)-len, ++ "%s key fingerprint is %s.%s%s\n%s", ++ type, fp, ++ options.visual_host_key ? "\n" : "", ++ options.visual_host_key ? ra : "", ++ msg2); ++ free(ra); ++ free(fp); ++ } ++ len = strlen(msg); ++ snprintf(msg+len, sizeof(msg)-len, + "Are you sure you want to continue connecting " +- "(yes/no)? ", +- host, ip, msg1, type, fp, +- options.visual_host_key ? "\n" : "", +- options.visual_host_key ? ra : "", +- msg2); +- free(ra); +- free(fp); ++ "(yes/no)? "); + if (!confirm(msg)) + goto fail; + hostkey_trusted = 1; /* user explicitly confirmed */ +@@ -1244,7 +1250,7 @@ verify_host_key(char *host, struct socka + struct sshkey *plain = NULL; + + if ((fp = sshkey_fingerprint(host_key, +- options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) { ++ options.fingerprint_hash[0], SSH_FP_DEFAULT)) == NULL) { + error("%s: fingerprint host key: %s", __func__, ssh_err(r)); + r = -1; + goto out; +@@ -1408,9 +1414,9 @@ show_other_keys(struct hostkeys *hostkey + if (!lookup_key_in_hostkeys_by_type(hostkeys, type[i], &found)) + continue; + fp = sshkey_fingerprint(found->key, +- options.fingerprint_hash, SSH_FP_DEFAULT); ++ options.fingerprint_hash[0], SSH_FP_DEFAULT); + ra = sshkey_fingerprint(found->key, +- options.fingerprint_hash, SSH_FP_RANDOMART); ++ options.fingerprint_hash[0], SSH_FP_RANDOMART); + if (fp == NULL || ra == NULL) + fatal("%s: sshkey_fingerprint fail", __func__); + logit("WARNING: %s key found for host %s\n" +@@ -1433,7 +1439,7 @@ warn_changed_key(Key *host_key) + { + char *fp; + +- fp = sshkey_fingerprint(host_key, options.fingerprint_hash, ++ fp = sshkey_fingerprint(host_key, options.fingerprint_hash[0], + SSH_FP_DEFAULT); + if (fp == NULL) + fatal("%s: sshkey_fingerprint fail", __func__); diff --git a/openssh.spec b/openssh.spec index 92960fe..770084d 100644 --- a/openssh.spec +++ b/openssh.spec @@ -232,7 +232,8 @@ Patch931: openssh-6.9p1-scp-progressmeter.patch # Privilege separation weakness related to PAM support (#1252844) # Use-after-free bug related to PAM support (#1252852) Patch932: openssh-6.9p1-security-7.0.patch - +# Possibility to validate legacy systems by more fingerprints (#1249626)(#2439) +Patch933: openssh-6.9p1-show-more-fingerprints.patch License: BSD @@ -458,6 +459,7 @@ popd %patch930 -p1 -b .kbd %patch931 -p1 -b .progressmeter %patch932 -p1 -b .security +%patch933 -p1 -b .fingerprint %patch200 -p1 -b .audit %patch700 -p1 -b .fips