diff options
-rw-r--r-- | auth-rh-rsa.c | 19 | ||||
-rw-r--r-- | auth-rsa.c | 19 | ||||
-rw-r--r-- | auth.c | 33 | ||||
-rw-r--r-- | auth.h | 2 | ||||
-rw-r--r-- | auth2-hostbased.c | 18 | ||||
-rw-r--r-- | auth2-pubkey.c | 18 | ||||
-rw-r--r-- | authfile.c | 19 | ||||
-rw-r--r-- | authfile.h | 2 | ||||
-rw-r--r-- | debian/changelog | 2 | ||||
-rw-r--r-- | ssh-vulnkey.c | 2 | ||||
-rw-r--r-- | sshd.c | 17 |
11 files changed, 63 insertions, 88 deletions
diff --git a/auth-rh-rsa.c b/auth-rh-rsa.c index cd272e4ca..20ee7c6c4 100644 --- a/auth-rh-rsa.c +++ b/auth-rh-rsa.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #include <pwd.h> | 20 | #include <pwd.h> |
21 | #include <stdarg.h> | 21 | #include <stdarg.h> |
22 | 22 | ||
23 | #include "xmalloc.h" | ||
24 | #include "packet.h" | 23 | #include "packet.h" |
25 | #include "uidswap.h" | 24 | #include "uidswap.h" |
26 | #include "log.h" | 25 | #include "log.h" |
@@ -28,7 +27,6 @@ | |||
28 | #include "servconf.h" | 27 | #include "servconf.h" |
29 | #include "key.h" | 28 | #include "key.h" |
30 | #include "hostfile.h" | 29 | #include "hostfile.h" |
31 | #include "authfile.h" | ||
32 | #include "pathnames.h" | 30 | #include "pathnames.h" |
33 | #include "auth.h" | 31 | #include "auth.h" |
34 | #include "canohost.h" | 32 | #include "canohost.h" |
@@ -44,23 +42,10 @@ int | |||
44 | auth_rhosts_rsa_key_allowed(struct passwd *pw, char *cuser, char *chost, | 42 | auth_rhosts_rsa_key_allowed(struct passwd *pw, char *cuser, char *chost, |
45 | Key *client_host_key) | 43 | Key *client_host_key) |
46 | { | 44 | { |
47 | char *fp; | ||
48 | HostStatus host_status; | 45 | HostStatus host_status; |
49 | 46 | ||
50 | if (blacklisted_key(client_host_key) == 1) { | 47 | if (reject_blacklisted_key(client_host_key, 0) == 1) |
51 | fp = key_fingerprint(client_host_key, SSH_FP_MD5, SSH_FP_HEX); | 48 | return 0; |
52 | if (options.permit_blacklisted_keys) | ||
53 | logit("Public key %s from %s blacklisted (see " | ||
54 | "ssh-vulnkey(1)); continuing anyway", | ||
55 | fp, get_remote_ipaddr()); | ||
56 | else | ||
57 | logit("Public key %s from %s blacklisted (see " | ||
58 | "ssh-vulnkey(1))", | ||
59 | fp, get_remote_ipaddr()); | ||
60 | xfree(fp); | ||
61 | if (!options.permit_blacklisted_keys) | ||
62 | return 0; | ||
63 | } | ||
64 | 49 | ||
65 | /* Check if we would accept it using rhosts authentication. */ | 50 | /* Check if we would accept it using rhosts authentication. */ |
66 | if (!auth_rhosts(pw, cuser)) | 51 | if (!auth_rhosts(pw, cuser)) |
diff --git a/auth-rsa.c b/auth-rsa.c index 898e9eb50..b7cbc0fe5 100644 --- a/auth-rsa.c +++ b/auth-rsa.c | |||
@@ -40,9 +40,7 @@ | |||
40 | #include "servconf.h" | 40 | #include "servconf.h" |
41 | #include "key.h" | 41 | #include "key.h" |
42 | #include "hostfile.h" | 42 | #include "hostfile.h" |
43 | #include "authfile.h" | ||
44 | #include "auth.h" | 43 | #include "auth.h" |
45 | #include "canohost.h" | ||
46 | #ifdef GSSAPI | 44 | #ifdef GSSAPI |
47 | #include "ssh-gss.h" | 45 | #include "ssh-gss.h" |
48 | #endif | 46 | #endif |
@@ -223,7 +221,6 @@ auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey) | |||
223 | char *cp; | 221 | char *cp; |
224 | char *key_options; | 222 | char *key_options; |
225 | int keybits; | 223 | int keybits; |
226 | char *fp; | ||
227 | 224 | ||
228 | /* Skip leading whitespace, empty and comment lines. */ | 225 | /* Skip leading whitespace, empty and comment lines. */ |
229 | for (cp = line; *cp == ' ' || *cp == '\t'; cp++) | 226 | for (cp = line; *cp == ' ' || *cp == '\t'; cp++) |
@@ -268,20 +265,8 @@ auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey) | |||
268 | "actual %d vs. announced %d.", | 265 | "actual %d vs. announced %d.", |
269 | file, linenum, BN_num_bits(key->rsa->n), bits); | 266 | file, linenum, BN_num_bits(key->rsa->n), bits); |
270 | 267 | ||
271 | if (blacklisted_key(key) == 1) { | 268 | if (reject_blacklisted_key(key, 0) == 1) |
272 | fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); | 269 | continue; |
273 | if (options.permit_blacklisted_keys) | ||
274 | logit("Public key %s from %s blacklisted (see " | ||
275 | "ssh-vulnkey(1)); continuing anyway", | ||
276 | fp, get_remote_ipaddr()); | ||
277 | else | ||
278 | logit("Public key %s from %s blacklisted (see " | ||
279 | "ssh-vulnkey(1))", | ||
280 | fp, get_remote_ipaddr()); | ||
281 | xfree(fp); | ||
282 | if (!options.permit_blacklisted_keys) | ||
283 | continue; | ||
284 | } | ||
285 | 270 | ||
286 | /* We have found the desired key. */ | 271 | /* We have found the desired key. */ |
287 | /* | 272 | /* |
@@ -57,6 +57,7 @@ | |||
57 | #include "servconf.h" | 57 | #include "servconf.h" |
58 | #include "key.h" | 58 | #include "key.h" |
59 | #include "hostfile.h" | 59 | #include "hostfile.h" |
60 | #include "authfile.h" | ||
60 | #include "auth.h" | 61 | #include "auth.h" |
61 | #include "auth-options.h" | 62 | #include "auth-options.h" |
62 | #include "canohost.h" | 63 | #include "canohost.h" |
@@ -397,6 +398,38 @@ check_key_in_hostfiles(struct passwd *pw, Key *key, const char *host, | |||
397 | return host_status; | 398 | return host_status; |
398 | } | 399 | } |
399 | 400 | ||
401 | int | ||
402 | reject_blacklisted_key(Key *key, int hostkey) | ||
403 | { | ||
404 | char *fp; | ||
405 | |||
406 | if (blacklisted_key(key, &fp) != 1) | ||
407 | return 0; | ||
408 | |||
409 | if (options.permit_blacklisted_keys) { | ||
410 | if (hostkey) | ||
411 | error("Host key %s blacklisted (see " | ||
412 | "ssh-vulnkey(1)); continuing anyway", fp); | ||
413 | else | ||
414 | logit("Public key %s from %s blacklisted (see " | ||
415 | "ssh-vulnkey(1)); continuing anyway", | ||
416 | fp, get_remote_ipaddr()); | ||
417 | xfree(fp); | ||
418 | } else { | ||
419 | if (hostkey) | ||
420 | error("Host key %s blacklisted (see " | ||
421 | "ssh-vulnkey(1))", fp); | ||
422 | else | ||
423 | logit("Public key %s from %s blacklisted (see " | ||
424 | "ssh-vulnkey(1))", | ||
425 | fp, get_remote_ipaddr()); | ||
426 | xfree(fp); | ||
427 | return 1; | ||
428 | } | ||
429 | |||
430 | return 0; | ||
431 | } | ||
432 | |||
400 | 433 | ||
401 | /* | 434 | /* |
402 | * Check a given file for security. This is defined as all components | 435 | * Check a given file for security. This is defined as all components |
@@ -175,6 +175,8 @@ HostStatus | |||
175 | check_key_in_hostfiles(struct passwd *, Key *, const char *, | 175 | check_key_in_hostfiles(struct passwd *, Key *, const char *, |
176 | const char *, const char *); | 176 | const char *, const char *); |
177 | 177 | ||
178 | int reject_blacklisted_key(Key *, int); | ||
179 | |||
178 | /* hostkey handling */ | 180 | /* hostkey handling */ |
179 | Key *get_hostkey_by_index(int); | 181 | Key *get_hostkey_by_index(int); |
180 | Key *get_hostkey_by_type(int); | 182 | Key *get_hostkey_by_type(int); |
diff --git a/auth2-hostbased.c b/auth2-hostbased.c index d7009eeb0..f6fb74043 100644 --- a/auth2-hostbased.c +++ b/auth2-hostbased.c | |||
@@ -40,7 +40,6 @@ | |||
40 | #include "compat.h" | 40 | #include "compat.h" |
41 | #include "key.h" | 41 | #include "key.h" |
42 | #include "hostfile.h" | 42 | #include "hostfile.h" |
43 | #include "authfile.h" | ||
44 | #include "auth.h" | 43 | #include "auth.h" |
45 | #include "canohost.h" | 44 | #include "canohost.h" |
46 | #ifdef GSSAPI | 45 | #ifdef GSSAPI |
@@ -142,25 +141,12 @@ int | |||
142 | hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost, | 141 | hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost, |
143 | Key *key) | 142 | Key *key) |
144 | { | 143 | { |
145 | char *fp; | ||
146 | const char *resolvedname, *ipaddr, *lookup; | 144 | const char *resolvedname, *ipaddr, *lookup; |
147 | HostStatus host_status; | 145 | HostStatus host_status; |
148 | int len; | 146 | int len; |
149 | 147 | ||
150 | if (blacklisted_key(key) == 1) { | 148 | if (reject_blacklisted_key(key, 0) == 1) |
151 | fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); | 149 | return 0; |
152 | if (options.permit_blacklisted_keys) | ||
153 | logit("Public key %s from %s blacklisted (see " | ||
154 | "ssh-vulnkey(1)); continuing anyway", | ||
155 | fp, get_remote_ipaddr()); | ||
156 | else | ||
157 | logit("Public key %s from %s blacklisted (see " | ||
158 | "ssh-vulnkey(1))", | ||
159 | fp, get_remote_ipaddr()); | ||
160 | xfree(fp); | ||
161 | if (!options.permit_blacklisted_keys) | ||
162 | return 0; | ||
163 | } | ||
164 | 150 | ||
165 | resolvedname = get_canonical_hostname(options.use_dns); | 151 | resolvedname = get_canonical_hostname(options.use_dns); |
166 | ipaddr = get_remote_ipaddr(); | 152 | ipaddr = get_remote_ipaddr(); |
diff --git a/auth2-pubkey.c b/auth2-pubkey.c index 0870d64f6..4f305ef1b 100644 --- a/auth2-pubkey.c +++ b/auth2-pubkey.c | |||
@@ -42,7 +42,6 @@ | |||
42 | #include "compat.h" | 42 | #include "compat.h" |
43 | #include "key.h" | 43 | #include "key.h" |
44 | #include "hostfile.h" | 44 | #include "hostfile.h" |
45 | #include "authfile.h" | ||
46 | #include "auth.h" | 45 | #include "auth.h" |
47 | #include "pathnames.h" | 46 | #include "pathnames.h" |
48 | #include "uidswap.h" | 47 | #include "uidswap.h" |
@@ -270,24 +269,11 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file) | |||
270 | int | 269 | int |
271 | user_key_allowed(struct passwd *pw, Key *key) | 270 | user_key_allowed(struct passwd *pw, Key *key) |
272 | { | 271 | { |
273 | char *fp; | ||
274 | int success; | 272 | int success; |
275 | char *file; | 273 | char *file; |
276 | 274 | ||
277 | if (blacklisted_key(key) == 1) { | 275 | if (reject_blacklisted_key(key, 0) == 1) |
278 | fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); | 276 | return 0; |
279 | if (options.permit_blacklisted_keys) | ||
280 | logit("Public key %s from %s blacklisted (see " | ||
281 | "ssh-vulnkey(1)); continuing anyway", | ||
282 | fp, get_remote_ipaddr()); | ||
283 | else | ||
284 | logit("Public key %s from %s blacklisted (see " | ||
285 | "ssh-vulnkey(1))", | ||
286 | fp, get_remote_ipaddr()); | ||
287 | xfree(fp); | ||
288 | if (!options.permit_blacklisted_keys) | ||
289 | return 0; | ||
290 | } | ||
291 | 277 | ||
292 | file = authorized_keys_file(pw); | 278 | file = authorized_keys_file(pw); |
293 | success = user_key_allowed2(pw, key, file); | 279 | success = user_key_allowed2(pw, key, file); |
diff --git a/authfile.c b/authfile.c index cffea2a6c..0d837b9bd 100644 --- a/authfile.c +++ b/authfile.c | |||
@@ -681,7 +681,7 @@ key_load_public(const char *filename, char **commentp) | |||
681 | 681 | ||
682 | /* Scan a blacklist of known-vulnerable keys in blacklist_file. */ | 682 | /* Scan a blacklist of known-vulnerable keys in blacklist_file. */ |
683 | static int | 683 | static int |
684 | blacklisted_key_in_file(const Key *key, const char *blacklist_file) | 684 | blacklisted_key_in_file(const Key *key, const char *blacklist_file, char **fp) |
685 | { | 685 | { |
686 | int fd = -1; | 686 | int fd = -1; |
687 | char *dgst_hex = NULL; | 687 | char *dgst_hex = NULL; |
@@ -770,16 +770,23 @@ blacklisted_key_in_file(const Key *key, const char *blacklist_file) | |||
770 | out: | 770 | out: |
771 | if (dgst_packed) | 771 | if (dgst_packed) |
772 | xfree(dgst_packed); | 772 | xfree(dgst_packed); |
773 | if (dgst_hex) | 773 | if (ret != 1 && dgst_hex) { |
774 | xfree(dgst_hex); | 774 | xfree(dgst_hex); |
775 | dgst_hex = NULL; | ||
776 | } | ||
777 | if (fp) | ||
778 | *fp = dgst_hex; | ||
775 | if (fd >= 0) | 779 | if (fd >= 0) |
776 | close(fd); | 780 | close(fd); |
777 | return ret; | 781 | return ret; |
778 | } | 782 | } |
779 | 783 | ||
780 | /* Scan blacklists of known-vulnerable keys. */ | 784 | /* |
785 | * Scan blacklists of known-vulnerable keys. If a vulnerable key is found, | ||
786 | * its fingerprint is returned in *fp, unless fp is NULL. | ||
787 | */ | ||
781 | int | 788 | int |
782 | blacklisted_key(const Key *key) | 789 | blacklisted_key(const Key *key, char **fp) |
783 | { | 790 | { |
784 | Key *public; | 791 | Key *public; |
785 | char *blacklist_file; | 792 | char *blacklist_file; |
@@ -791,7 +798,7 @@ blacklisted_key(const Key *key) | |||
791 | 798 | ||
792 | xasprintf(&blacklist_file, "%s.%s-%u", | 799 | xasprintf(&blacklist_file, "%s.%s-%u", |
793 | _PATH_BLACKLIST, key_type(public), key_size(public)); | 800 | _PATH_BLACKLIST, key_type(public), key_size(public)); |
794 | ret = blacklisted_key_in_file(public, blacklist_file); | 801 | ret = blacklisted_key_in_file(public, blacklist_file, fp); |
795 | xfree(blacklist_file); | 802 | xfree(blacklist_file); |
796 | if (ret > 0) { | 803 | if (ret > 0) { |
797 | key_free(public); | 804 | key_free(public); |
@@ -800,7 +807,7 @@ blacklisted_key(const Key *key) | |||
800 | 807 | ||
801 | xasprintf(&blacklist_file, "%s.%s-%u", | 808 | xasprintf(&blacklist_file, "%s.%s-%u", |
802 | _PATH_BLACKLIST_CONFIG, key_type(public), key_size(public)); | 809 | _PATH_BLACKLIST_CONFIG, key_type(public), key_size(public)); |
803 | ret2 = blacklisted_key_in_file(public, blacklist_file); | 810 | ret2 = blacklisted_key_in_file(public, blacklist_file, fp); |
804 | xfree(blacklist_file); | 811 | xfree(blacklist_file); |
805 | if (ret2 > ret) | 812 | if (ret2 > ret) |
806 | ret = ret2; | 813 | ret = ret2; |
diff --git a/authfile.h b/authfile.h index 91557e4a2..e4f59fddb 100644 --- a/authfile.h +++ b/authfile.h | |||
@@ -23,6 +23,6 @@ Key *key_load_private_type(int, const char *, const char *, char **, int *); | |||
23 | Key *key_load_private_pem(int, int, const char *, char **); | 23 | Key *key_load_private_pem(int, int, const char *, char **); |
24 | int key_perm_ok(int, const char *); | 24 | int key_perm_ok(int, const char *); |
25 | 25 | ||
26 | int blacklisted_key(const Key *key); | 26 | int blacklisted_key(const Key *key, char **fp); |
27 | 27 | ||
28 | #endif | 28 | #endif |
diff --git a/debian/changelog b/debian/changelog index 81db5f171..c42a3c50d 100644 --- a/debian/changelog +++ b/debian/changelog | |||
@@ -1,6 +1,8 @@ | |||
1 | openssh (1:4.7p1-12) UNRELEASED; urgency=low | 1 | openssh (1:4.7p1-12) UNRELEASED; urgency=low |
2 | 2 | ||
3 | * Fill in CVE identifier for ssh-vulnkey bug fixed in 1:4.7p1-10. | 3 | * Fill in CVE identifier for ssh-vulnkey bug fixed in 1:4.7p1-10. |
4 | * Refactor rejection of blacklisted user keys into a single | ||
5 | reject_blacklisted_key function in auth.c (thanks, Dmitry V. Levin). | ||
4 | * debconf template translations: | 6 | * debconf template translations: |
5 | - Update Dutch (thanks, Bart Cornelis; closes: #483004). | 7 | - Update Dutch (thanks, Bart Cornelis; closes: #483004). |
6 | 8 | ||
diff --git a/ssh-vulnkey.c b/ssh-vulnkey.c index e0e3f4c2f..31d252b43 100644 --- a/ssh-vulnkey.c +++ b/ssh-vulnkey.c | |||
@@ -105,7 +105,7 @@ do_key(const char *filename, u_long linenum, | |||
105 | if (public->type == KEY_RSA1) | 105 | if (public->type == KEY_RSA1) |
106 | public->type = KEY_RSA; | 106 | public->type = KEY_RSA; |
107 | 107 | ||
108 | blacklist_status = blacklisted_key(public); | 108 | blacklist_status = blacklisted_key(public, NULL); |
109 | if (blacklist_status == -1) | 109 | if (blacklist_status == -1) |
110 | describe_key(filename, linenum, | 110 | describe_key(filename, linenum, |
111 | "Unknown (blacklist file not installed)", key, comment, 0); | 111 | "Unknown (blacklist file not installed)", key, comment, 0); |
@@ -1496,20 +1496,9 @@ main(int ac, char **av) | |||
1496 | 1496 | ||
1497 | for (i = 0; i < options.num_host_key_files; i++) { | 1497 | for (i = 0; i < options.num_host_key_files; i++) { |
1498 | key = key_load_private(options.host_key_files[i], "", NULL); | 1498 | key = key_load_private(options.host_key_files[i], "", NULL); |
1499 | if (key && blacklisted_key(key) == 1) { | 1499 | if (key && reject_blacklisted_key(key, 1) == 1) { |
1500 | char *fp; | 1500 | sensitive_data.host_keys[i] = NULL; |
1501 | fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); | 1501 | continue; |
1502 | if (options.permit_blacklisted_keys) | ||
1503 | error("Host key %s blacklisted (see " | ||
1504 | "ssh-vulnkey(1)); continuing anyway", fp); | ||
1505 | else | ||
1506 | error("Host key %s blacklisted (see " | ||
1507 | "ssh-vulnkey(1))", fp); | ||
1508 | xfree(fp); | ||
1509 | if (!options.permit_blacklisted_keys) { | ||
1510 | sensitive_data.host_keys[i] = NULL; | ||
1511 | continue; | ||
1512 | } | ||
1513 | } | 1502 | } |
1514 | sensitive_data.host_keys[i] = key; | 1503 | sensitive_data.host_keys[i] = key; |
1515 | if (key == NULL) { | 1504 | if (key == NULL) { |