summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog10
-rw-r--r--auth2-hostbased.c8
-rw-r--r--auth2-pubkey.c8
-rw-r--r--compat.c61
-rw-r--r--compat.h3
-rw-r--r--ssh-rsa.c23
-rw-r--r--sshconnect.c5
-rw-r--r--sshconnect2.c33
-rw-r--r--sshd.c13
9 files changed, 109 insertions, 55 deletions
diff --git a/ChangeLog b/ChangeLog
index d33de38a7..7b5123412 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
120131231
2 - (djm) OpenBSD CVS Sync
3 - djm@cvs.openbsd.org 2013/12/30 23:52:28
4 [auth2-hostbased.c auth2-pubkey.c compat.c compat.h ssh-rsa.c]
5 [sshconnect.c sshconnect2.c sshd.c]
6 refuse RSA keys from old proprietary clients/servers that use the
7 obsolete RSA+MD5 signature scheme. it will still be possible to connect
8 with these clients/servers but only DSA keys will be accepted, and we'll
9 deprecate them entirely in a future release. ok markus@
10
120131229 1120131229
2 - (djm) [loginrec.c] Check for username truncation when looking up lastlog 12 - (djm) [loginrec.c] Check for username truncation when looking up lastlog
3 entries 13 entries
diff --git a/auth2-hostbased.c b/auth2-hostbased.c
index a344dcc1f..488008f62 100644
--- a/auth2-hostbased.c
+++ b/auth2-hostbased.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth2-hostbased.c,v 1.16 2013/06/21 00:34:49 djm Exp $ */ 1/* $OpenBSD: auth2-hostbased.c,v 1.17 2013/12/30 23:52:27 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * 4 *
@@ -100,6 +100,12 @@ userauth_hostbased(Authctxt *authctxt)
100 "(received %d, expected %d)", key->type, pktype); 100 "(received %d, expected %d)", key->type, pktype);
101 goto done; 101 goto done;
102 } 102 }
103 if (key_type_plain(key->type) == KEY_RSA &&
104 (datafellows & SSH_BUG_RSASIGMD5) != 0) {
105 error("Refusing RSA key because peer uses unsafe "
106 "signature format");
107 goto done;
108 }
103 service = datafellows & SSH_BUG_HBSERVICE ? "ssh-userauth" : 109 service = datafellows & SSH_BUG_HBSERVICE ? "ssh-userauth" :
104 authctxt->service; 110 authctxt->service;
105 buffer_init(&b); 111 buffer_init(&b);
diff --git a/auth2-pubkey.c b/auth2-pubkey.c
index 2b3ecb104..0fd27bb92 100644
--- a/auth2-pubkey.c
+++ b/auth2-pubkey.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth2-pubkey.c,v 1.38 2013/06/21 00:34:49 djm Exp $ */ 1/* $OpenBSD: auth2-pubkey.c,v 1.39 2013/12/30 23:52:27 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * 4 *
@@ -116,6 +116,12 @@ userauth_pubkey(Authctxt *authctxt)
116 "(received %d, expected %d)", key->type, pktype); 116 "(received %d, expected %d)", key->type, pktype);
117 goto done; 117 goto done;
118 } 118 }
119 if (key_type_plain(key->type) == KEY_RSA &&
120 (datafellows & SSH_BUG_RSASIGMD5) != 0) {
121 logit("Refusing RSA key because client uses unsafe "
122 "signature scheme");
123 goto done;
124 }
119 if (have_sig) { 125 if (have_sig) {
120 sig = packet_get_string(&slen); 126 sig = packet_get_string(&slen);
121 packet_check_eom(); 127 packet_check_eom();
diff --git a/compat.c b/compat.c
index ac353a706..9d9fabef3 100644
--- a/compat.c
+++ b/compat.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: compat.c,v 1.81 2013/05/17 00:13:13 djm Exp $ */ 1/* $OpenBSD: compat.c,v 1.82 2013/12/30 23:52:27 djm Exp $ */
2/* 2/*
3 * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved. 3 * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved.
4 * 4 *
@@ -171,8 +171,9 @@ compat_datafellows(const char *version)
171 for (i = 0; check[i].pat; i++) { 171 for (i = 0; check[i].pat; i++) {
172 if (match_pattern_list(version, check[i].pat, 172 if (match_pattern_list(version, check[i].pat,
173 strlen(check[i].pat), 0) == 1) { 173 strlen(check[i].pat), 0) == 1) {
174 debug("match: %s pat %s", version, check[i].pat);
175 datafellows = check[i].bugs; 174 datafellows = check[i].bugs;
175 debug("match: %s pat %s compat 0x%08x",
176 version, check[i].pat, datafellows);
176 return; 177 return;
177 } 178 }
178 } 179 }
@@ -208,33 +209,59 @@ proto_spec(const char *spec)
208 return ret; 209 return ret;
209} 210}
210 211
211char * 212/*
212compat_cipher_proposal(char *cipher_prop) 213 * Filters a proposal string, excluding any algorithm matching the 'filter'
214 * pattern list.
215 */
216static char *
217filter_proposal(char *proposal, const char *filter)
213{ 218{
214 Buffer b; 219 Buffer b;
215 char *orig_prop, *fix_ciphers; 220 char *orig_prop, *fix_prop;
216 char *cp, *tmp; 221 char *cp, *tmp;
217 222
218 if (!(datafellows & SSH_BUG_BIGENDIANAES))
219 return(cipher_prop);
220
221 buffer_init(&b); 223 buffer_init(&b);
222 tmp = orig_prop = xstrdup(cipher_prop); 224 tmp = orig_prop = xstrdup(proposal);
223 while ((cp = strsep(&tmp, ",")) != NULL) { 225 while ((cp = strsep(&tmp, ",")) != NULL) {
224 if (strncmp(cp, "aes", 3) != 0) { 226 if (match_pattern_list(cp, filter, strlen(cp), 0) != 1) {
225 if (buffer_len(&b) > 0) 227 if (buffer_len(&b) > 0)
226 buffer_append(&b, ",", 1); 228 buffer_append(&b, ",", 1);
227 buffer_append(&b, cp, strlen(cp)); 229 buffer_append(&b, cp, strlen(cp));
228 } 230 } else
231 debug2("Compat: skipping algorithm \"%s\"", cp);
229 } 232 }
230 buffer_append(&b, "\0", 1); 233 buffer_append(&b, "\0", 1);
231 fix_ciphers = xstrdup(buffer_ptr(&b)); 234 fix_prop = xstrdup(buffer_ptr(&b));
232 buffer_free(&b); 235 buffer_free(&b);
233 free(orig_prop); 236 free(orig_prop);
234 debug2("Original cipher proposal: %s", cipher_prop);
235 debug2("Compat cipher proposal: %s", fix_ciphers);
236 if (!*fix_ciphers)
237 fatal("No available ciphers found.");
238 237
239 return(fix_ciphers); 238 return fix_prop;
240} 239}
240
241char *
242compat_cipher_proposal(char *cipher_prop)
243{
244 if (!(datafellows & SSH_BUG_BIGENDIANAES))
245 return cipher_prop;
246 debug2("%s: original cipher proposal: %s", __func__, cipher_prop);
247 cipher_prop = filter_proposal(cipher_prop, "aes*");
248 debug2("%s: compat cipher proposal: %s", __func__, cipher_prop);
249 if (*cipher_prop == '\0')
250 fatal("No supported ciphers found");
251 return cipher_prop;
252}
253
254
255char *
256compat_pkalg_proposal(char *pkalg_prop)
257{
258 if (!(datafellows & SSH_BUG_RSASIGMD5))
259 return pkalg_prop;
260 debug2("%s: original public key proposal: %s", __func__, pkalg_prop);
261 pkalg_prop = filter_proposal(pkalg_prop, "ssh-rsa");
262 debug2("%s: compat public key proposal: %s", __func__, pkalg_prop);
263 if (*pkalg_prop == '\0')
264 fatal("No supported PK algorithms found");
265 return pkalg_prop;
266}
267
diff --git a/compat.h b/compat.h
index 3ae5d9c78..b174fa171 100644
--- a/compat.h
+++ b/compat.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: compat.h,v 1.43 2011/09/23 07:45:05 markus Exp $ */ 1/* $OpenBSD: compat.h,v 1.44 2013/12/30 23:52:27 djm Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved. 4 * Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved.
@@ -65,6 +65,7 @@ void enable_compat20(void);
65void compat_datafellows(const char *); 65void compat_datafellows(const char *);
66int proto_spec(const char *); 66int proto_spec(const char *);
67char *compat_cipher_proposal(char *); 67char *compat_cipher_proposal(char *);
68char *compat_pkalg_proposal(char *);
68 69
69extern int compat13; 70extern int compat13;
70extern int compat20; 71extern int compat20;
diff --git a/ssh-rsa.c b/ssh-rsa.c
index 6e28bb4a6..b1ac50b31 100644
--- a/ssh-rsa.c
+++ b/ssh-rsa.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-rsa.c,v 1.48 2013/12/27 22:37:18 djm Exp $ */ 1/* $OpenBSD: ssh-rsa.c,v 1.49 2013/12/30 23:52:27 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000, 2003 Markus Friedl <markus@openbsd.org> 3 * Copyright (c) 2000, 2003 Markus Friedl <markus@openbsd.org>
4 * 4 *
@@ -53,7 +53,7 @@ ssh_rsa_sign(const Key *key, u_char **sigp, u_int *lenp,
53 return -1; 53 return -1;
54 } 54 }
55 55
56 nid = (datafellows & SSH_BUG_RSASIGMD5) ? NID_md5 : NID_sha1; 56 nid = NID_sha1;
57 if ((evp_md = EVP_get_digestbynid(nid)) == NULL) { 57 if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
58 error("%s: EVP_get_digestbynid %d failed", __func__, nid); 58 error("%s: EVP_get_digestbynid %d failed", __func__, nid);
59 return -1; 59 return -1;
@@ -161,7 +161,7 @@ ssh_rsa_verify(const Key *key, const u_char *signature, u_int signaturelen,
161 memset(sigblob, 0, diff); 161 memset(sigblob, 0, diff);
162 len = modlen; 162 len = modlen;
163 } 163 }
164 nid = (datafellows & SSH_BUG_RSASIGMD5) ? NID_md5 : NID_sha1; 164 nid = NID_sha1;
165 if ((evp_md = EVP_get_digestbynid(nid)) == NULL) { 165 if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
166 error("%s: EVP_get_digestbynid %d failed", __func__, nid); 166 error("%s: EVP_get_digestbynid %d failed", __func__, nid);
167 free(sigblob); 167 free(sigblob);
@@ -196,18 +196,6 @@ static const u_char id_sha1[] = {
196 0x05, 0x00, /* NULL */ 196 0x05, 0x00, /* NULL */
197 0x04, 0x14 /* Octet string, length 0x14 (20), followed by sha1 hash */ 197 0x04, 0x14 /* Octet string, length 0x14 (20), followed by sha1 hash */
198}; 198};
199/*
200 * id-md5 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840)
201 * rsadsi(113549) digestAlgorithm(2) 5 }
202 */
203static const u_char id_md5[] = {
204 0x30, 0x20, /* type Sequence, length 0x20 (32) */
205 0x30, 0x0c, /* type Sequence, length 0x0c (12) */
206 0x06, 0x08, /* type OID, length 0x08 */
207 0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, /* id-md5 */
208 0x05, 0x00, /* NULL */
209 0x04, 0x10 /* Octet string, length 0x10 (16), followed by md5 hash */
210};
211 199
212static int 200static int
213openssh_RSA_verify(int type, u_char *hash, u_int hashlen, 201openssh_RSA_verify(int type, u_char *hash, u_int hashlen,
@@ -225,11 +213,6 @@ openssh_RSA_verify(int type, u_char *hash, u_int hashlen,
225 oidlen = sizeof(id_sha1); 213 oidlen = sizeof(id_sha1);
226 hlen = 20; 214 hlen = 20;
227 break; 215 break;
228 case NID_md5:
229 oid = id_md5;
230 oidlen = sizeof(id_md5);
231 hlen = 16;
232 break;
233 default: 216 default:
234 goto done; 217 goto done;
235 } 218 }
diff --git a/sshconnect.c b/sshconnect.c
index b492ce915..791b31c12 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshconnect.c,v 1.242 2013/12/29 05:57:02 djm Exp $ */ 1/* $OpenBSD: sshconnect.c,v 1.243 2013/12/30 23:52:27 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -662,6 +662,9 @@ ssh_exchange_identification(int timeout_ms)
662 fatal("Protocol major versions differ: %d vs. %d", 662 fatal("Protocol major versions differ: %d vs. %d",
663 (options.protocol & SSH_PROTO_2) ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1, 663 (options.protocol & SSH_PROTO_2) ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1,
664 remote_major); 664 remote_major);
665 if ((datafellows & SSH_BUG_RSASIGMD5) != 0)
666 logit("Server version \"%.100s\" uses unsafe RSA signature "
667 "scheme; disabling use of RSA keys", remote_version);
665 if (!client_banner_sent) 668 if (!client_banner_sent)
666 send_client_banner(connection_out, minor1); 669 send_client_banner(connection_out, minor1);
667 chop(server_version_string); 670 chop(server_version_string);
diff --git a/sshconnect2.c b/sshconnect2.c
index 1f6160e86..0d339b9c5 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshconnect2.c,v 1.199 2013/11/02 21:59:15 markus Exp $ */ 1/* $OpenBSD: sshconnect2.c,v 1.200 2013/12/30 23:52:28 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * Copyright (c) 2008 Damien Miller. All rights reserved. 4 * Copyright (c) 2008 Damien Miller. All rights reserved.
@@ -188,11 +188,12 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port)
188 } 188 }
189 if (options.hostkeyalgorithms != NULL) 189 if (options.hostkeyalgorithms != NULL)
190 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = 190 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =
191 options.hostkeyalgorithms; 191 compat_pkalg_proposal(options.hostkeyalgorithms);
192 else { 192 else {
193 /* Prefer algorithms that we already have keys for */ 193 /* Prefer algorithms that we already have keys for */
194 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = 194 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =
195 order_hostkeyalgs(host, hostaddr, port); 195 compat_pkalg_proposal(
196 order_hostkeyalgs(host, hostaddr, port));
196 } 197 }
197 if (options.kex_algorithms != NULL) 198 if (options.kex_algorithms != NULL)
198 myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms; 199 myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms;
@@ -1489,17 +1490,31 @@ userauth_pubkey(Authctxt *authctxt)
1489 * encrypted keys we cannot do this and have to load the 1490 * encrypted keys we cannot do this and have to load the
1490 * private key instead 1491 * private key instead
1491 */ 1492 */
1492 if (id->key && id->key->type != KEY_RSA1) { 1493 if (id->key != NULL) {
1493 debug("Offering %s public key: %s", key_type(id->key), 1494 if (key_type_plain(id->key->type) == KEY_RSA &&
1494 id->filename); 1495 (datafellows & SSH_BUG_RSASIGMD5) != 0) {
1495 sent = send_pubkey_test(authctxt, id); 1496 debug("Skipped %s key %s for RSA/MD5 server",
1496 } else if (id->key == NULL) { 1497 key_type(id->key), id->filename);
1498 } else if (id->key->type != KEY_RSA1) {
1499 debug("Offering %s public key: %s",
1500 key_type(id->key), id->filename);
1501 sent = send_pubkey_test(authctxt, id);
1502 }
1503 } else {
1497 debug("Trying private key: %s", id->filename); 1504 debug("Trying private key: %s", id->filename);
1498 id->key = load_identity_file(id->filename, 1505 id->key = load_identity_file(id->filename,
1499 id->userprovided); 1506 id->userprovided);
1500 if (id->key != NULL) { 1507 if (id->key != NULL) {
1501 id->isprivate = 1; 1508 id->isprivate = 1;
1502 sent = sign_and_send_pubkey(authctxt, id); 1509 if (key_type_plain(id->key->type) == KEY_RSA &&
1510 (datafellows & SSH_BUG_RSASIGMD5) != 0) {
1511 debug("Skipped %s key %s for RSA/MD5 "
1512 "server", key_type(id->key),
1513 id->filename);
1514 } else {
1515 sent = sign_and_send_pubkey(
1516 authctxt, id);
1517 }
1503 key_free(id->key); 1518 key_free(id->key);
1504 id->key = NULL; 1519 id->key = NULL;
1505 } 1520 }
diff --git a/sshd.c b/sshd.c
index 786d9ff90..87795bea5 100644
--- a/sshd.c
+++ b/sshd.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshd.c,v 1.412 2013/12/06 13:39:49 markus Exp $ */ 1/* $OpenBSD: sshd.c,v 1.413 2013/12/30 23:52:28 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -492,17 +492,19 @@ sshd_exchange_identification(int sock_in, int sock_out)
492 492
493 compat_datafellows(remote_version); 493 compat_datafellows(remote_version);
494 494
495 if (datafellows & SSH_BUG_PROBE) { 495 if ((datafellows & SSH_BUG_PROBE) != 0) {
496 logit("probed from %s with %s. Don't panic.", 496 logit("probed from %s with %s. Don't panic.",
497 get_remote_ipaddr(), client_version_string); 497 get_remote_ipaddr(), client_version_string);
498 cleanup_exit(255); 498 cleanup_exit(255);
499 } 499 }
500 500 if ((datafellows & SSH_BUG_SCANNER) != 0) {
501 if (datafellows & SSH_BUG_SCANNER) {
502 logit("scanned from %s with %s. Don't panic.", 501 logit("scanned from %s with %s. Don't panic.",
503 get_remote_ipaddr(), client_version_string); 502 get_remote_ipaddr(), client_version_string);
504 cleanup_exit(255); 503 cleanup_exit(255);
505 } 504 }
505 if ((datafellows & SSH_BUG_RSASIGMD5) != 0)
506 logit("Client version \"%.100s\" uses unsafe RSA signature "
507 "scheme; disabling use of RSA keys", remote_version);
506 508
507 mismatch = 0; 509 mismatch = 0;
508 switch (remote_major) { 510 switch (remote_major) {
@@ -2446,7 +2448,8 @@ do_ssh2_kex(void)
2446 packet_set_rekey_limits((u_int32_t)options.rekey_limit, 2448 packet_set_rekey_limits((u_int32_t)options.rekey_limit,
2447 (time_t)options.rekey_interval); 2449 (time_t)options.rekey_interval);
2448 2450
2449 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = list_hostkey_types(); 2451 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal(
2452 list_hostkey_types());
2450 2453
2451 /* start key exchange */ 2454 /* start key exchange */
2452 kex = kex_setup(myproposal); 2455 kex = kex_setup(myproposal);