View | Details | Raw Unified | Return to bug 2131
Collapse All | Expand All

(-)a/auth.c (-2 / +2 lines)
Lines 402-408 check_key_in_hostfiles(struct passwd *pw, Key *key, const char *host, Link Here
402
	const struct hostkey_entry *found;
402
	const struct hostkey_entry *found;
403
403
404
	hostkeys = init_hostkeys();
404
	hostkeys = init_hostkeys();
405
	load_hostkeys(hostkeys, host, sysfile);
405
	load_hostkeys(hostkeys, host, NULL, sysfile);
406
	if (userfile != NULL) {
406
	if (userfile != NULL) {
407
		user_hostfile = tilde_expand_filename(userfile, pw->pw_uid);
407
		user_hostfile = tilde_expand_filename(userfile, pw->pw_uid);
408
		if (options.strict_modes &&
408
		if (options.strict_modes &&
Lines 416-422 check_key_in_hostfiles(struct passwd *pw, Key *key, const char *host, Link Here
416
			    user_hostfile);
416
			    user_hostfile);
417
		} else {
417
		} else {
418
			temporarily_use_uid(pw);
418
			temporarily_use_uid(pw);
419
			load_hostkeys(hostkeys, host, user_hostfile);
419
			load_hostkeys(hostkeys, host, NULL, user_hostfile);
420
			restore_uid();
420
			restore_uid();
421
		}
421
		}
422
		free(user_hostfile);
422
		free(user_hostfile);
(-)a/hostfile.c (-14 / +28 lines)
Lines 58-68 Link Here
58
#include "log.h"
58
#include "log.h"
59
#include "misc.h"
59
#include "misc.h"
60
60
61
struct hostkeys {
62
	struct hostkey_entry *entries;
63
	u_int num_entries;
64
};
65
66
static int
61
static int
67
extract_salt(const char *s, u_int l, u_char *salt, size_t salt_len)
62
extract_salt(const char *s, u_int l, u_char *salt, size_t salt_len)
68
{
63
{
Lines 239-258 init_hostkeys(void) Link Here
239
}
234
}
240
235
241
void
236
void
242
load_hostkeys(struct hostkeys *hostkeys, const char *host, const char *path)
237
load_hostkeys(struct hostkeys *hostkeys, const char *lookup_host,
238
    const Key *lookup_key, const char *path)
243
{
239
{
244
	FILE *f;
240
	FILE *f;
245
	char line[8192];
241
	char line[8192];
246
	u_long linenum = 0, num_loaded = 0;
242
	u_long linenum = 0, num_loaded = 0;
247
	char *cp, *cp2, *hashed_host;
243
	char *cp, *cp2, *hashed_host;
244
	const char *current_host;
248
	HostkeyMarker marker;
245
	HostkeyMarker marker;
249
	Key *key;
246
	Key *key;
250
	int kbits;
247
	int kbits;
251
248
252
	if ((f = fopen(path, "r")) == NULL)
249
	if ((f = fopen(path, "r")) == NULL)
253
		return;
250
		return;
254
	debug3("%s: loading entries for host \"%.100s\" from file \"%s\"",
251
	debug3("%s: loading entries for host \"%.100s\"%s from file \"%s\"",
255
	    __func__, host, path);
252
	    __func__, lookup_host, (lookup_key ? " and key" : ""), path);
256
	while (read_keyfile_line(f, path, line, sizeof(line), &linenum) == 0) {
253
	while (read_keyfile_line(f, path, line, sizeof(line), &linenum) == 0) {
257
		cp = line;
254
		cp = line;
258
255
Lines 272-282 load_hostkeys(struct hostkeys *hostkeys, const char *host, const char *path) Link Here
272
		for (cp2 = cp; *cp2 && *cp2 != ' ' && *cp2 != '\t'; cp2++)
269
		for (cp2 = cp; *cp2 && *cp2 != ' ' && *cp2 != '\t'; cp2++)
273
			;
270
			;
274
271
275
		/* Check if the host name matches. */
272
		/* Check if the host name matches if we're looking for a host. */
276
		if (match_hostname(host, cp, (u_int) (cp2 - cp)) != 1) {
273
		if (lookup_host && match_hostname(lookup_host, cp, (u_int) (cp2 - cp)) != 1) {
277
			if (*cp != HASH_DELIM)
274
			if (*cp != HASH_DELIM)
278
				continue;
275
				continue;
279
			hashed_host = host_hash(host, cp, (u_int) (cp2 - cp));
276
			hashed_host = host_hash(lookup_host, cp, (u_int) (cp2 - cp));
280
			if (hashed_host == NULL) {
277
			if (hashed_host == NULL) {
281
				debug("Invalid hashed host line %lu of %s",
278
				debug("Invalid hashed host line %lu of %s",
282
				    linenum, path);
279
				    linenum, path);
Lines 286-292 load_hostkeys(struct hostkeys *hostkeys, const char *host, const char *path) Link Here
286
				continue;
283
				continue;
287
		}
284
		}
288
285
289
		/* Got a match.  Skip host name. */
286
		/* If we're looking for a key grab the hostname and ignore hashed entries. */
287
		if (lookup_key) {
288
			if (*cp == HASH_DELIM)
289
				continue;
290
			*cp2++ = 0;
291
			current_host = cp;
292
		} else {
293
			current_host = lookup_host;
294
		}
295
296
		/* Move pointer past the hostname. */
290
		cp = cp2;
297
		cp = cp2;
291
298
292
		/*
299
		/*
Lines 302-308 load_hostkeys(struct hostkeys *hostkeys, const char *host, const char *path) Link Here
302
				continue;
309
				continue;
303
			}
310
			}
304
		}
311
		}
305
		if (!hostfile_check_key(kbits, key, host, path, linenum))
312
313
		/* Check if the key matches if we're looking for a key. */
314
		if (lookup_key) {
315
		        if (!key_equal(lookup_key, key))
316
		                continue;
317
		}
318
319
		if (!hostfile_check_key(kbits, key, current_host, path, linenum))
306
			continue;
320
			continue;
307
321
308
		debug3("%s: found %skey type %s in file %s:%lu", __func__,
322
		debug3("%s: found %skey type %s in file %s:%lu", __func__,
Lines 311-317 load_hostkeys(struct hostkeys *hostkeys, const char *host, const char *path) Link Here
311
		    key_type(key), path, linenum);
325
		    key_type(key), path, linenum);
312
		hostkeys->entries = xrealloc(hostkeys->entries,
326
		hostkeys->entries = xrealloc(hostkeys->entries,
313
		    hostkeys->num_entries + 1, sizeof(*hostkeys->entries));
327
		    hostkeys->num_entries + 1, sizeof(*hostkeys->entries));
314
		hostkeys->entries[hostkeys->num_entries].host = xstrdup(host);
328
		hostkeys->entries[hostkeys->num_entries].host = xstrdup(current_host);
315
		hostkeys->entries[hostkeys->num_entries].file = xstrdup(path);
329
		hostkeys->entries[hostkeys->num_entries].file = xstrdup(path);
316
		hostkeys->entries[hostkeys->num_entries].line = linenum;
330
		hostkeys->entries[hostkeys->num_entries].line = linenum;
317
		hostkeys->entries[hostkeys->num_entries].key = key;
331
		hostkeys->entries[hostkeys->num_entries].key = key;
(-)a/hostfile.h (-2 / +6 lines)
Lines 29-38 struct hostkey_entry { Link Here
29
	Key *key;
29
	Key *key;
30
	HostkeyMarker marker;
30
	HostkeyMarker marker;
31
};
31
};
32
struct hostkeys;
32
33
struct hostkeys {
34
	struct hostkey_entry *entries;
35
	u_int num_entries;
36
};
33
37
34
struct hostkeys *init_hostkeys(void);
38
struct hostkeys *init_hostkeys(void);
35
void	 load_hostkeys(struct hostkeys *, const char *, const char *);
39
void	 load_hostkeys(struct hostkeys *, const char *, const Key *, const char *);
36
void	 free_hostkeys(struct hostkeys *);
40
void	 free_hostkeys(struct hostkeys *);
37
41
38
HostStatus check_key_in_hostkeys(struct hostkeys *, Key *,
42
HostStatus check_key_in_hostkeys(struct hostkeys *, Key *,
(-)a/sshconnect.c (-6 / +33 lines)
Lines 724-736 check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, Link Here
724
	Key *raw_key = NULL;
724
	Key *raw_key = NULL;
725
	char *ip = NULL, *host = NULL;
725
	char *ip = NULL, *host = NULL;
726
	char hostline[1000], *hostp, *fp, *ra;
726
	char hostline[1000], *hostp, *fp, *ra;
727
	char msg[1024];
727
	char msg[2048];
728
	const char *type;
728
	const char *type;
729
	const struct hostkey_entry *host_found, *ip_found;
729
	const struct hostkey_entry *host_found, *ip_found;
730
	int len, cancelled_forwarding = 0;
730
	int len, cancelled_forwarding = 0;
731
	int local = sockaddr_is_local(hostaddr);
731
	int local = sockaddr_is_local(hostaddr);
732
	int r, want_cert = key_is_cert(host_key), host_ip_differ = 0;
732
	int r, want_cert = key_is_cert(host_key), host_ip_differ = 0;
733
	struct hostkeys *host_hostkeys, *ip_hostkeys;
733
	struct hostkeys *host_hostkeys, *ip_hostkeys, *key_hostkeys = NULL;
734
	u_int i;
734
	u_int i;
735
735
736
	/*
736
	/*
Lines 764-780 check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, Link Here
764
764
765
	host_hostkeys = init_hostkeys();
765
	host_hostkeys = init_hostkeys();
766
	for (i = 0; i < num_user_hostfiles; i++)
766
	for (i = 0; i < num_user_hostfiles; i++)
767
		load_hostkeys(host_hostkeys, host, user_hostfiles[i]);
767
		load_hostkeys(host_hostkeys, host, NULL, user_hostfiles[i]);
768
	for (i = 0; i < num_system_hostfiles; i++)
768
	for (i = 0; i < num_system_hostfiles; i++)
769
		load_hostkeys(host_hostkeys, host, system_hostfiles[i]);
769
		load_hostkeys(host_hostkeys, host, NULL, system_hostfiles[i]);
770
770
771
	ip_hostkeys = NULL;
771
	ip_hostkeys = NULL;
772
	if (!want_cert && options.check_host_ip) {
772
	if (!want_cert && options.check_host_ip) {
773
		ip_hostkeys = init_hostkeys();
773
		ip_hostkeys = init_hostkeys();
774
		for (i = 0; i < num_user_hostfiles; i++)
774
		for (i = 0; i < num_user_hostfiles; i++)
775
			load_hostkeys(ip_hostkeys, ip, user_hostfiles[i]);
775
			load_hostkeys(ip_hostkeys, ip, NULL, user_hostfiles[i]);
776
		for (i = 0; i < num_system_hostfiles; i++)
776
		for (i = 0; i < num_system_hostfiles; i++)
777
			load_hostkeys(ip_hostkeys, ip, system_hostfiles[i]);
777
			load_hostkeys(ip_hostkeys, ip, NULL, system_hostfiles[i]);
778
	}
778
	}
779
779
780
 retry:
780
 retry:
Lines 885-890 check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, Link Here
885
					    "No matching host key fingerprint"
885
					    "No matching host key fingerprint"
886
					    " found in DNS.\n");
886
					    " found in DNS.\n");
887
			}
887
			}
888
			/* Has this key been accepted for other hostnames? */
889
			key_hostkeys = init_hostkeys();
890
			for (i = 0; i < num_user_hostfiles; i++)
891
				load_hostkeys(key_hostkeys, NULL, host_key,
892
				    user_hostfiles[i]);
893
			for (i = 0; i < num_system_hostfiles; i++)
894
				load_hostkeys(key_hostkeys, NULL, host_key,
895
				    system_hostfiles[i]);
896
			if (key_hostkeys->num_entries > 0) {
897
				strlcat(msg2, "You have previously accepted "
898
				    "this key for the following hostnames:",
899
				    sizeof(msg2));
900
				for (i = 0; i < key_hostkeys->num_entries; i++) {
901
					strlcat(msg2, "\n\t", sizeof(msg2));
902
					strlcat(msg2, key_hostkeys->entries[i].host,
903
					    sizeof(msg2));
904
				}
905
				if (strlcat(msg2, "\n", sizeof(msg2)) >=
906
				    sizeof(msg2)) {
907
					/* truncate at last newline. */
908
					*(strrchr(msg2, '\n') + 1) = 0;
909
				}
910
			}
888
			snprintf(msg, sizeof(msg),
911
			snprintf(msg, sizeof(msg),
889
			    "The authenticity of host '%.200s (%s)' can't be "
912
			    "The authenticity of host '%.200s (%s)' can't be "
890
			    "established%s\n"
913
			    "established%s\n"
Lines 1103-1108 check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, Link Here
1103
		free_hostkeys(host_hostkeys);
1126
		free_hostkeys(host_hostkeys);
1104
	if (ip_hostkeys != NULL)
1127
	if (ip_hostkeys != NULL)
1105
		free_hostkeys(ip_hostkeys);
1128
		free_hostkeys(ip_hostkeys);
1129
	if (key_hostkeys != NULL)
1130
		free_hostkeys(key_hostkeys);
1106
	return 0;
1131
	return 0;
1107
1132
1108
fail:
1133
fail:
Lines 1126-1131 fail: Link Here
1126
		free_hostkeys(host_hostkeys);
1151
		free_hostkeys(host_hostkeys);
1127
	if (ip_hostkeys != NULL)
1152
	if (ip_hostkeys != NULL)
1128
		free_hostkeys(ip_hostkeys);
1153
		free_hostkeys(ip_hostkeys);
1154
	if (key_hostkeys != NULL)
1155
		free_hostkeys(key_hostkeys);
1129
	return -1;
1156
	return -1;
1130
}
1157
}
1131
1158
(-)a/sshconnect2.c (-3 / +2 lines)
Lines 115-123 order_hostkeyalgs(char *host, struct sockaddr *hostaddr, u_short port) Link Here
115
	get_hostfile_hostname_ipaddr(host, hostaddr, port, &hostname, NULL);
115
	get_hostfile_hostname_ipaddr(host, hostaddr, port, &hostname, NULL);
116
	hostkeys = init_hostkeys();
116
	hostkeys = init_hostkeys();
117
	for (i = 0; i < options.num_user_hostfiles; i++)
117
	for (i = 0; i < options.num_user_hostfiles; i++)
118
		load_hostkeys(hostkeys, hostname, options.user_hostfiles[i]);
118
		load_hostkeys(hostkeys, hostname, NULL, options.user_hostfiles[i]);
119
	for (i = 0; i < options.num_system_hostfiles; i++)
119
	for (i = 0; i < options.num_system_hostfiles; i++)
120
		load_hostkeys(hostkeys, hostname, options.system_hostfiles[i]);
120
		load_hostkeys(hostkeys, hostname, NULL, options.system_hostfiles[i]);
121
121
122
	oavail = avail = xstrdup(KEX_DEFAULT_PK_ALG);
122
	oavail = avail = xstrdup(KEX_DEFAULT_PK_ALG);
123
	maxlen = strlen(avail) + 1;
123
	maxlen = strlen(avail) + 1;
124
- 

Return to bug 2131