Bugzilla – Attachment 2320 Details for
Bug 2131
ssh: list known names (if any) for new hostkeys
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
list known names (if any) for new hostkeys
0001-hostfile-list-known-names-if-any-for-new-hostkeys.patch (text/plain), 9.13 KB, created by
Oskari Saarenmaa
on 2013-07-25 20:51:35 AEST
(
hide
)
Description:
list known names (if any) for new hostkeys
Filename:
MIME Type:
Creator:
Oskari Saarenmaa
Created:
2013-07-25 20:51:35 AEST
Size:
9.13 KB
patch
obsolete
>From e3630bbf70dfadda544c0e8c38c998ae72a141f9 Mon Sep 17 00:00:00 2001 >From: Oskari Saarenmaa <os@ohmu.fi> >Date: Thu, 25 Jul 2013 13:45:51 +0300 >Subject: [PATCH] hostfile: list known names (if any) for new hostkeys > >When connecting to a host for which there's no known hostkey, check if the >relevant key has been accepted for other hostnames. This is useful when >connecting to a host with a dynamic IP address or multiple names. >--- > auth.c | 4 ++-- > hostfile.c | 42 ++++++++++++++++++++++++++++-------------- > hostfile.h | 8 ++++++-- > sshconnect.c | 39 +++++++++++++++++++++++++++++++++------ > sshconnect2.c | 4 ++-- > 5 files changed, 71 insertions(+), 26 deletions(-) > >diff --git a/auth.c b/auth.c >index 9a36f1d..7532847 100644 >--- a/auth.c >+++ b/auth.c >@@ -402,7 +402,7 @@ check_key_in_hostfiles(struct passwd *pw, Key *key, const char *host, > const struct hostkey_entry *found; > > hostkeys = init_hostkeys(); >- load_hostkeys(hostkeys, host, sysfile); >+ load_hostkeys(hostkeys, host, NULL, sysfile); > if (userfile != NULL) { > user_hostfile = tilde_expand_filename(userfile, pw->pw_uid); > if (options.strict_modes && >@@ -416,7 +416,7 @@ check_key_in_hostfiles(struct passwd *pw, Key *key, const char *host, > user_hostfile); > } else { > temporarily_use_uid(pw); >- load_hostkeys(hostkeys, host, user_hostfile); >+ load_hostkeys(hostkeys, host, NULL, user_hostfile); > restore_uid(); > } > free(user_hostfile); >diff --git a/hostfile.c b/hostfile.c >index 2ff4c48..aaaa0ea 100644 >--- a/hostfile.c >+++ b/hostfile.c >@@ -58,11 +58,6 @@ > #include "log.h" > #include "misc.h" > >-struct hostkeys { >- struct hostkey_entry *entries; >- u_int num_entries; >-}; >- > static int > extract_salt(const char *s, u_int l, u_char *salt, size_t salt_len) > { >@@ -239,20 +234,22 @@ init_hostkeys(void) > } > > void >-load_hostkeys(struct hostkeys *hostkeys, const char *host, const char *path) >+load_hostkeys(struct hostkeys *hostkeys, const char *lookup_host, >+ const Key *lookup_key, const char *path) > { > FILE *f; > char line[8192]; > u_long linenum = 0, num_loaded = 0; > char *cp, *cp2, *hashed_host; >+ const char *current_host; > HostkeyMarker marker; > Key *key; > int kbits; > > if ((f = fopen(path, "r")) == NULL) > return; >- debug3("%s: loading entries for host \"%.100s\" from file \"%s\"", >- __func__, host, path); >+ debug3("%s: loading entries for host \"%.100s\"%s from file \"%s\"", >+ __func__, lookup_host, (lookup_key ? " and key" : ""), path); > while (read_keyfile_line(f, path, line, sizeof(line), &linenum) == 0) { > cp = line; > >@@ -272,11 +269,11 @@ load_hostkeys(struct hostkeys *hostkeys, const char *host, const char *path) > for (cp2 = cp; *cp2 && *cp2 != ' ' && *cp2 != '\t'; cp2++) > ; > >- /* Check if the host name matches. */ >- if (match_hostname(host, cp, (u_int) (cp2 - cp)) != 1) { >+ /* Check if the host name matches if we're looking for a host. */ >+ if (lookup_host && match_hostname(lookup_host, cp, (u_int) (cp2 - cp)) != 1) { > if (*cp != HASH_DELIM) > continue; >- hashed_host = host_hash(host, cp, (u_int) (cp2 - cp)); >+ hashed_host = host_hash(lookup_host, cp, (u_int) (cp2 - cp)); > if (hashed_host == NULL) { > debug("Invalid hashed host line %lu of %s", > linenum, path); >@@ -286,7 +283,17 @@ load_hostkeys(struct hostkeys *hostkeys, const char *host, const char *path) > continue; > } > >- /* Got a match. Skip host name. */ >+ /* If we're looking for a key grab the hostname and ignore hashed entries. */ >+ if (lookup_key) { >+ if (*cp == HASH_DELIM) >+ continue; >+ *cp2++ = 0; >+ current_host = cp; >+ } else { >+ current_host = lookup_host; >+ } >+ >+ /* Move pointer past the hostname. */ > cp = cp2; > > /* >@@ -302,7 +309,14 @@ load_hostkeys(struct hostkeys *hostkeys, const char *host, const char *path) > continue; > } > } >- if (!hostfile_check_key(kbits, key, host, path, linenum)) >+ >+ /* Check if the key matches if we're looking for a key. */ >+ if (lookup_key) { >+ if (!key_equal(lookup_key, key)) >+ continue; >+ } >+ >+ if (!hostfile_check_key(kbits, key, current_host, path, linenum)) > continue; > > debug3("%s: found %skey type %s in file %s:%lu", __func__, >@@ -311,7 +325,7 @@ load_hostkeys(struct hostkeys *hostkeys, const char *host, const char *path) > key_type(key), path, linenum); > hostkeys->entries = xrealloc(hostkeys->entries, > hostkeys->num_entries + 1, sizeof(*hostkeys->entries)); >- hostkeys->entries[hostkeys->num_entries].host = xstrdup(host); >+ hostkeys->entries[hostkeys->num_entries].host = xstrdup(current_host); > hostkeys->entries[hostkeys->num_entries].file = xstrdup(path); > hostkeys->entries[hostkeys->num_entries].line = linenum; > hostkeys->entries[hostkeys->num_entries].key = key; >diff --git a/hostfile.h b/hostfile.h >index 679c034..726c48b 100644 >--- a/hostfile.h >+++ b/hostfile.h >@@ -29,10 +29,14 @@ struct hostkey_entry { > Key *key; > HostkeyMarker marker; > }; >-struct hostkeys; >+ >+struct hostkeys { >+ struct hostkey_entry *entries; >+ u_int num_entries; >+}; > > struct hostkeys *init_hostkeys(void); >-void load_hostkeys(struct hostkeys *, const char *, const char *); >+void load_hostkeys(struct hostkeys *, const char *, const Key *, const char *); > void free_hostkeys(struct hostkeys *); > > HostStatus check_key_in_hostkeys(struct hostkeys *, Key *, >diff --git a/sshconnect.c b/sshconnect.c >index 483eb85..c9b0109 100644 >--- a/sshconnect.c >+++ b/sshconnect.c >@@ -724,13 +724,13 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, > Key *raw_key = NULL; > char *ip = NULL, *host = NULL; > char hostline[1000], *hostp, *fp, *ra; >- char msg[1024]; >+ char msg[2048]; > const char *type; > const struct hostkey_entry *host_found, *ip_found; > int len, cancelled_forwarding = 0; > int local = sockaddr_is_local(hostaddr); > int r, want_cert = key_is_cert(host_key), host_ip_differ = 0; >- struct hostkeys *host_hostkeys, *ip_hostkeys; >+ struct hostkeys *host_hostkeys, *ip_hostkeys, *key_hostkeys = NULL; > u_int i; > > /* >@@ -764,17 +764,17 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, > > host_hostkeys = init_hostkeys(); > for (i = 0; i < num_user_hostfiles; i++) >- load_hostkeys(host_hostkeys, host, user_hostfiles[i]); >+ load_hostkeys(host_hostkeys, host, NULL, user_hostfiles[i]); > for (i = 0; i < num_system_hostfiles; i++) >- load_hostkeys(host_hostkeys, host, system_hostfiles[i]); >+ load_hostkeys(host_hostkeys, host, NULL, system_hostfiles[i]); > > ip_hostkeys = NULL; > if (!want_cert && options.check_host_ip) { > ip_hostkeys = init_hostkeys(); > for (i = 0; i < num_user_hostfiles; i++) >- load_hostkeys(ip_hostkeys, ip, user_hostfiles[i]); >+ load_hostkeys(ip_hostkeys, ip, NULL, user_hostfiles[i]); > for (i = 0; i < num_system_hostfiles; i++) >- load_hostkeys(ip_hostkeys, ip, system_hostfiles[i]); >+ load_hostkeys(ip_hostkeys, ip, NULL, system_hostfiles[i]); > } > > retry: >@@ -885,6 +885,29 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, > "No matching host key fingerprint" > " found in DNS.\n"); > } >+ /* Has this key been accepted for other hostnames? */ >+ key_hostkeys = init_hostkeys(); >+ for (i = 0; i < num_user_hostfiles; i++) >+ load_hostkeys(key_hostkeys, NULL, host_key, >+ user_hostfiles[i]); >+ for (i = 0; i < num_system_hostfiles; i++) >+ load_hostkeys(key_hostkeys, NULL, host_key, >+ system_hostfiles[i]); >+ if (key_hostkeys->num_entries > 0) { >+ strlcat(msg2, "You have previously accepted " >+ "this key for the following hostnames:", >+ sizeof(msg2)); >+ for (i = 0; i < key_hostkeys->num_entries; i++) { >+ strlcat(msg2, "\n\t", sizeof(msg2)); >+ strlcat(msg2, key_hostkeys->entries[i].host, >+ sizeof(msg2)); >+ } >+ if (strlcat(msg2, "\n", sizeof(msg2)) >= >+ sizeof(msg2)) { >+ /* truncate at last newline. */ >+ *(strrchr(msg2, '\n') + 1) = 0; >+ } >+ } > snprintf(msg, sizeof(msg), > "The authenticity of host '%.200s (%s)' can't be " > "established%s\n" >@@ -1103,6 +1126,8 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, > free_hostkeys(host_hostkeys); > if (ip_hostkeys != NULL) > free_hostkeys(ip_hostkeys); >+ if (key_hostkeys != NULL) >+ free_hostkeys(key_hostkeys); > return 0; > > fail: >@@ -1126,6 +1151,8 @@ fail: > free_hostkeys(host_hostkeys); > if (ip_hostkeys != NULL) > free_hostkeys(ip_hostkeys); >+ if (key_hostkeys != NULL) >+ free_hostkeys(key_hostkeys); > return -1; > } > >diff --git a/sshconnect2.c b/sshconnect2.c >index 70e3cd8..314aa6b 100644 >--- a/sshconnect2.c >+++ b/sshconnect2.c >@@ -115,9 +115,9 @@ order_hostkeyalgs(char *host, struct sockaddr *hostaddr, u_short port) > get_hostfile_hostname_ipaddr(host, hostaddr, port, &hostname, NULL); > hostkeys = init_hostkeys(); > for (i = 0; i < options.num_user_hostfiles; i++) >- load_hostkeys(hostkeys, hostname, options.user_hostfiles[i]); >+ load_hostkeys(hostkeys, hostname, NULL, options.user_hostfiles[i]); > for (i = 0; i < options.num_system_hostfiles; i++) >- load_hostkeys(hostkeys, hostname, options.system_hostfiles[i]); >+ load_hostkeys(hostkeys, hostname, NULL, options.system_hostfiles[i]); > > oavail = avail = xstrdup(KEX_DEFAULT_PK_ALG); > maxlen = strlen(avail) + 1; >-- >1.8.3.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 2131
: 2320