- djm@cvs.openbsd.org 2010/08/31 09:58:37
     [auth-options.c auth1.c auth2.c bufaux.c buffer.h kex.c key.c packet.c]
     [packet.h ssh-dss.c ssh-rsa.c]
     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.
diff --git a/bufaux.c b/bufaux.c
index 854fd51..00208ca 100644
--- a/bufaux.c
+++ b/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
@@ -202,6 +202,39 @@
 	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)
 {