summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorDamien Miller <djm@cvs.openbsd.org>2010-08-31 09:58:38 +0000
committerDamien Miller <djm@cvs.openbsd.org>2010-08-31 09:58:38 +0000
commitfac9264a5a14dde04909fa5d6f9d716e54ff2f9c (patch)
tree2ea15924a879e2b3fcc5245ca9171ed590ddd425 /usr.bin
parenta3c5a70ad71e8adf3896b2779ca78e4278e02a2d (diff)
Add buffer_get_cstring() and related functions that verify that the
string extracted from the buffer contains no embedded \0 characters* This prevents random (possibly malicious) crap from being appended to strings where it would not be noticed if the string is used with a string(3) function. Use the new API in a few sensitive places. * actually, we allow a single one at the end of the string for now because we don't know how many deployed implementations get this wrong, but don't count on this to remain indefinitely.
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/ssh/auth-options.c8
-rw-r--r--usr.bin/ssh/auth1.c6
-rw-r--r--usr.bin/ssh/auth2.c10
-rw-r--r--usr.bin/ssh/bufaux.c35
-rw-r--r--usr.bin/ssh/buffer.h4
-rw-r--r--usr.bin/ssh/kex.c4
-rw-r--r--usr.bin/ssh/key.c13
-rw-r--r--usr.bin/ssh/packet.c9
-rw-r--r--usr.bin/ssh/packet.h3
-rw-r--r--usr.bin/ssh/ssh-dss.c4
-rw-r--r--usr.bin/ssh/ssh-rsa.c4
11 files changed, 69 insertions, 31 deletions
diff --git a/usr.bin/ssh/auth-options.c b/usr.bin/ssh/auth-options.c
index 5cfe9ebd533..89c40f6000a 100644
--- a/usr.bin/ssh/auth-options.c
+++ b/usr.bin/ssh/auth-options.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth-options.c,v 1.52 2010/05/20 23:46:02 djm Exp $ */
+/* $OpenBSD: auth-options.c,v 1.53 2010/08/31 09:58:37 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -442,7 +442,7 @@ parse_option_list(u_char *optblob, size_t optblob_len, struct passwd *pw,
buffer_append(&c, optblob, optblob_len);
while (buffer_len(&c) > 0) {
- if ((name = buffer_get_string_ret(&c, &nlen)) == NULL ||
+ if ((name = buffer_get_cstring_ret(&c, &nlen)) == NULL ||
(data_blob = buffer_get_string_ret(&c, &dlen)) == NULL) {
error("Certificate options corrupt");
goto out;
@@ -477,7 +477,7 @@ parse_option_list(u_char *optblob, size_t optblob_len, struct passwd *pw,
}
if (!found && (which & OPTIONS_CRITICAL) != 0) {
if (strcmp(name, "force-command") == 0) {
- if ((command = buffer_get_string_ret(&data,
+ if ((command = buffer_get_cstring_ret(&data,
&clen)) == NULL) {
error("Certificate constraint \"%s\" "
"corrupt", name);
@@ -498,7 +498,7 @@ parse_option_list(u_char *optblob, size_t optblob_len, struct passwd *pw,
found = 1;
}
if (strcmp(name, "source-address") == 0) {
- if ((allowed = buffer_get_string_ret(&data,
+ if ((allowed = buffer_get_cstring_ret(&data,
&clen)) == NULL) {
error("Certificate constraint "
"\"%s\" corrupt", name);
diff --git a/usr.bin/ssh/auth1.c b/usr.bin/ssh/auth1.c
index 73361042084..63fecc19e92 100644
--- a/usr.bin/ssh/auth1.c
+++ b/usr.bin/ssh/auth1.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth1.c,v 1.74 2010/06/25 08:46:17 djm Exp $ */
+/* $OpenBSD: auth1.c,v 1.75 2010/08/31 09:58:37 djm Exp $ */
/*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
@@ -161,7 +161,7 @@ auth1_process_rhosts_rsa(Authctxt *authctxt, char *info, size_t infolen)
* trust the client; root on the client machine can
* claim to be any user.
*/
- client_user = packet_get_string(&ulen);
+ client_user = packet_get_cstring(&ulen);
/* Get the client host key. */
client_host_key = key_new(KEY_RSA1);
@@ -321,7 +321,7 @@ do_authentication(Authctxt *authctxt)
packet_read_expect(SSH_CMSG_USER);
/* Get the user name. */
- user = packet_get_string(&ulen);
+ user = packet_get_cstring(&ulen);
packet_check_eom();
if ((style = strchr(user, ':')) != NULL)
diff --git a/usr.bin/ssh/auth2.c b/usr.bin/ssh/auth2.c
index c8d2f4efa2d..b197315f60f 100644
--- a/usr.bin/ssh/auth2.c
+++ b/usr.bin/ssh/auth2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth2.c,v 1.121 2009/06/22 05:39:28 dtucker Exp $ */
+/* $OpenBSD: auth2.c,v 1.122 2010/08/31 09:58:37 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@@ -169,7 +169,7 @@ input_service_request(int type, u_int32_t seq, void *ctxt)
Authctxt *authctxt = ctxt;
u_int len;
int acceptit = 0;
- char *service = packet_get_string(&len);
+ char *service = packet_get_cstring(&len);
packet_check_eom();
if (authctxt == NULL)
@@ -208,9 +208,9 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
if (authctxt == NULL)
fatal("input_userauth_request: no authctxt");
- user = packet_get_string(NULL);
- service = packet_get_string(NULL);
- method = packet_get_string(NULL);
+ user = packet_get_cstring(NULL);
+ service = packet_get_cstring(NULL);
+ method = packet_get_cstring(NULL);
debug("userauth-request for user %s service %s method %s", user, service, method);
debug("attempt %d failures %d", authctxt->attempt, authctxt->failures);
diff --git a/usr.bin/ssh/bufaux.c b/usr.bin/ssh/bufaux.c
index 8a889611714..f5a5d881222 100644
--- a/usr.bin/ssh/bufaux.c
+++ b/usr.bin/ssh/bufaux.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bufaux.c,v 1.49 2010/03/26 03:13:17 djm Exp $ */
+/* $OpenBSD: bufaux.c,v 1.50 2010/08/31 09:58:37 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -200,6 +200,39 @@ buffer_get_string(Buffer *buffer, u_int *length_ptr)
return (ret);
}
+char *
+buffer_get_cstring_ret(Buffer *buffer, u_int *length_ptr)
+{
+ u_int length;
+ char *cp, *ret = buffer_get_string_ret(buffer, &length);
+
+ if (ret == NULL)
+ return NULL;
+ if ((cp = memchr(ret, '\0', length)) != NULL) {
+ /* XXX allow \0 at end-of-string for a while, remove later */
+ if (cp == ret + length - 1)
+ error("buffer_get_cstring_ret: string contains \\0");
+ else {
+ bzero(ret, length);
+ xfree(ret);
+ return NULL;
+ }
+ }
+ if (length_ptr != NULL)
+ *length_ptr = length;
+ return ret;
+}
+
+char *
+buffer_get_cstring(Buffer *buffer, u_int *length_ptr)
+{
+ char *ret;
+
+ if ((ret = buffer_get_cstring_ret(buffer, length_ptr)) == NULL)
+ fatal("buffer_get_cstring: buffer error");
+ return ret;
+}
+
void *
buffer_get_string_ptr_ret(Buffer *buffer, u_int *length_ptr)
{
diff --git a/usr.bin/ssh/buffer.h b/usr.bin/ssh/buffer.h
index 4ef4f80b35a..93baae2c820 100644
--- a/usr.bin/ssh/buffer.h
+++ b/usr.bin/ssh/buffer.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: buffer.h,v 1.19 2010/02/09 03:56:28 djm Exp $ */
+/* $OpenBSD: buffer.h,v 1.20 2010/08/31 09:58:37 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -68,6 +68,7 @@ void buffer_put_char(Buffer *, int);
void *buffer_get_string(Buffer *, u_int *);
void *buffer_get_string_ptr(Buffer *, u_int *);
void buffer_put_string(Buffer *, const void *, u_int);
+char *buffer_get_cstring(Buffer *, u_int *);
void buffer_put_cstring(Buffer *, const char *);
#define buffer_skip_string(b) \
@@ -81,6 +82,7 @@ int buffer_get_short_ret(u_short *, Buffer *);
int buffer_get_int_ret(u_int *, Buffer *);
int buffer_get_int64_ret(u_int64_t *, Buffer *);
void *buffer_get_string_ret(Buffer *, u_int *);
+char *buffer_get_cstring_ret(Buffer *, u_int *);
void *buffer_get_string_ptr_ret(Buffer *, u_int *);
int buffer_get_char_ret(char *, Buffer *);
diff --git a/usr.bin/ssh/kex.c b/usr.bin/ssh/kex.c
index e7bd7a48a9f..c8d339824f3 100644
--- a/usr.bin/ssh/kex.c
+++ b/usr.bin/ssh/kex.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kex.c,v 1.82 2009/10/24 11:13:54 andreas Exp $ */
+/* $OpenBSD: kex.c,v 1.83 2010/08/31 09:58:37 djm Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
*
@@ -87,7 +87,7 @@ kex_buf2prop(Buffer *raw, int *first_kex_follows)
buffer_get_char(&b);
/* extract kex init proposal strings */
for (i = 0; i < PROPOSAL_MAX; i++) {
- proposal[i] = buffer_get_string(&b,NULL);
+ proposal[i] = buffer_get_cstring(&b,NULL);
debug2("kex_parse_kexinit: %s", proposal[i]);
}
/* first kex follows / reserved */
diff --git a/usr.bin/ssh/key.c b/usr.bin/ssh/key.c
index d3431de94fc..16ee2f960b9 100644
--- a/usr.bin/ssh/key.c
+++ b/usr.bin/ssh/key.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: key.c,v 1.90 2010/07/13 23:13:16 djm Exp $ */
+/* $OpenBSD: key.c,v 1.91 2010/08/31 09:58:37 djm Exp $ */
/*
* read_bignum():
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -1063,7 +1063,7 @@ cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen)
principals = exts = critical = sig_key = sig = NULL;
if ((!v00 && buffer_get_int64_ret(&key->cert->serial, b) != 0) ||
buffer_get_int_ret(&key->cert->type, b) != 0 ||
- (key->cert->key_id = buffer_get_string_ret(b, &kidlen)) == NULL ||
+ (key->cert->key_id = buffer_get_cstring_ret(b, &kidlen)) == NULL ||
(principals = buffer_get_string_ret(b, &plen)) == NULL ||
buffer_get_int64_ret(&key->cert->valid_after, b) != 0 ||
buffer_get_int64_ret(&key->cert->valid_before, b) != 0 ||
@@ -1101,15 +1101,10 @@ cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen)
error("%s: Too many principals", __func__);
goto out;
}
- if ((principal = buffer_get_string_ret(&tmp, &plen)) == NULL) {
+ if ((principal = buffer_get_cstring_ret(&tmp, &plen)) == NULL) {
error("%s: Principals data invalid", __func__);
goto out;
}
- if (strlen(principal) != plen) {
- error("%s: Principal contains \\0 character",
- __func__);
- goto out;
- }
key->cert->principals = xrealloc(key->cert->principals,
key->cert->nprincipals + 1, sizeof(*key->cert->principals));
key->cert->principals[key->cert->nprincipals++] = principal;
@@ -1196,7 +1191,7 @@ key_from_blob(const u_char *blob, u_int blen)
#endif
buffer_init(&b);
buffer_append(&b, blob, blen);
- if ((ktype = buffer_get_string_ret(&b, NULL)) == NULL) {
+ if ((ktype = buffer_get_cstring_ret(&b, NULL)) == NULL) {
error("key_from_blob: can't read key type");
goto out;
}
diff --git a/usr.bin/ssh/packet.c b/usr.bin/ssh/packet.c
index d948890cf0e..711a232c77e 100644
--- a/usr.bin/ssh/packet.c
+++ b/usr.bin/ssh/packet.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: packet.c,v 1.168 2010/07/13 23:13:16 djm Exp $ */
+/* $OpenBSD: packet.c,v 1.169 2010/08/31 09:58:37 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -1536,6 +1536,13 @@ packet_get_string_ptr(u_int *length_ptr)
return buffer_get_string_ptr(&active_state->incoming_packet, length_ptr);
}
+/* Ensures the returned string has no embedded \0 characters in it. */
+char *
+packet_get_cstring(u_int *length_ptr)
+{
+ return buffer_get_cstring(&active_state->incoming_packet, length_ptr);
+}
+
/*
* Sends a diagnostic message from the server to the client. This message
* can be sent at any time (but not while constructing another message). The
diff --git a/usr.bin/ssh/packet.h b/usr.bin/ssh/packet.h
index 33523d7503c..fd0b056fd88 100644
--- a/usr.bin/ssh/packet.h
+++ b/usr.bin/ssh/packet.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: packet.h,v 1.52 2009/06/27 09:29:06 andreas Exp $ */
+/* $OpenBSD: packet.h,v 1.53 2010/08/31 09:58:37 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -61,6 +61,7 @@ void packet_get_bignum(BIGNUM * value);
void packet_get_bignum2(BIGNUM * value);
void *packet_get_raw(u_int *length_ptr);
void *packet_get_string(u_int *length_ptr);
+char *packet_get_cstring(u_int *length_ptr);
void *packet_get_string_ptr(u_int *length_ptr);
void packet_disconnect(const char *fmt,...) __attribute__((format(printf, 1, 2)));
void packet_send_debug(const char *fmt,...) __attribute__((format(printf, 1, 2)));
diff --git a/usr.bin/ssh/ssh-dss.c b/usr.bin/ssh/ssh-dss.c
index 719f350f29b..9ffd87fabd9 100644
--- a/usr.bin/ssh/ssh-dss.c
+++ b/usr.bin/ssh/ssh-dss.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-dss.c,v 1.26 2010/04/16 01:47:26 djm Exp $ */
+/* $OpenBSD: ssh-dss.c,v 1.27 2010/08/31 09:58:37 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@@ -130,7 +130,7 @@ ssh_dss_verify(const Key *key, const u_char *signature, u_int signaturelen,
char *ktype;
buffer_init(&b);
buffer_append(&b, signature, signaturelen);
- ktype = buffer_get_string(&b, NULL);
+ ktype = buffer_get_cstring(&b, NULL);
if (strcmp("ssh-dss", ktype) != 0) {
error("ssh_dss_verify: cannot handle type %s", ktype);
buffer_free(&b);
diff --git a/usr.bin/ssh/ssh-rsa.c b/usr.bin/ssh/ssh-rsa.c
index b29546783a2..5766582976f 100644
--- a/usr.bin/ssh/ssh-rsa.c
+++ b/usr.bin/ssh/ssh-rsa.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-rsa.c,v 1.44 2010/07/16 14:07:35 djm Exp $ */
+/* $OpenBSD: ssh-rsa.c,v 1.45 2010/08/31 09:58:37 djm Exp $ */
/*
* Copyright (c) 2000, 2003 Markus Friedl <markus@openbsd.org>
*
@@ -124,7 +124,7 @@ ssh_rsa_verify(const Key *key, const u_char *signature, u_int signaturelen,
}
buffer_init(&b);
buffer_append(&b, signature, signaturelen);
- ktype = buffer_get_string(&b, NULL);
+ ktype = buffer_get_cstring(&b, NULL);
if (strcmp("ssh-rsa", ktype) != 0) {
error("ssh_rsa_verify: cannot handle type %s", ktype);
buffer_free(&b);