$NetBSD: patch-aa,v 1.4 2009/04/18 19:27:11 tonnerre Exp $

--- src/protocol_auth.c.orig	2008-12-22 21:35:45.000000000 +0100
+++ src/protocol_auth.c
@@ -128,10 +128,10 @@ bool send_metakey(connection_t *c)
 
 	/* Allocate buffers for the meta key */
 
-	buffer = alloca(2 * len + 1);
+	buffer = xmalloc_and_zero(2 * len + 1);
 	
 	if(!c->outkey)
-		c->outkey = xmalloc(len);
+		c->outkey = xmalloc_and_zero(len);
 
 	if(!c->outctx)
 		c->outctx = xmalloc_and_zero(sizeof(*c->outctx));
@@ -169,6 +169,7 @@ bool send_metakey(connection_t *c)
 	if(RSA_public_encrypt(len, (unsigned char *)c->outkey, (unsigned char *)buffer, c->rsa_key, RSA_NO_PADDING) != len) {
 		logger(LOG_ERR, _("Error during encryption of meta key for %s (%s)"),
 			   c->name, c->hostname);
+		free(buffer);
 		return false;
 	}
 
@@ -193,35 +194,45 @@ bool send_metakey(connection_t *c)
 					c->outcipher->iv_len)) {
 			logger(LOG_ERR, _("Error during initialisation of cipher for %s (%s): %s"),
 					c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL));
+			free(buffer);
 			return false;
 		}
 
 		c->status.encryptout = true;
 	}
 
+	free(buffer);
 	return x;
 }
 
 bool metakey_h(connection_t *c)
 {
-	char buffer[MAX_STRING_SIZE];
+	char *buffer, fmt[513];
 	int cipher, digest, maclength, compression;
 	int len;
 
 	cp();
 
-	if(sscanf(c->buffer, "%*d %d %d %d %d " MAX_STRING, &cipher, &digest, &maclength, &compression, buffer) != 5) {
+	len = RSA_size(myself->connection->rsa_key);
+	buffer = xmalloc(2 * len + 1);
+	memset(buffer, 0, 2 * len + 1);
+
+	memset(fmt, 0, 513);
+	snprintf(fmt, 512, "%%*d %%d %%d %%d %%d %%%ds", 2 * len);
+
+	if(sscanf(c->buffer, fmt, &cipher, &digest, &maclength, &compression, buffer) != 5) {
 		logger(LOG_ERR, _("Got bad %s from %s (%s)"), "METAKEY", c->name,
 			   c->hostname);
+		free(buffer);
 		return false;
 	}
 
-	len = RSA_size(myself->connection->rsa_key);
 
 	/* Check if the length of the meta key is all right */
 
 	if(strlen(buffer) != len * 2) {
 		logger(LOG_ERR, _("Possible intruder %s (%s): %s"), c->name, c->hostname, "wrong keylength");
+		free(buffer);
 		return false;
 	}
 
@@ -260,6 +271,7 @@ bool metakey_h(connection_t *c)
 		
 		if(!c->incipher) {
 			logger(LOG_ERR, _("%s (%s) uses unknown cipher!"), c->name, c->hostname);
+			free(buffer);
 			return false;
 		}
 
@@ -269,6 +281,7 @@ bool metakey_h(connection_t *c)
 					c->incipher->iv_len)) {
 			logger(LOG_ERR, _("Error during initialisation of cipher from %s (%s): %s"),
 					c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL));
+			free(buffer);
 			return false;
 		}
 
@@ -284,11 +297,13 @@ bool metakey_h(connection_t *c)
 
 		if(!c->indigest) {
 			logger(LOG_ERR, _("Node %s (%s) uses unknown digest!"), c->name, c->hostname);
+			free(buffer);
 			return false;
 		}
 
 		if(c->inmaclength > c->indigest->md_size || c->inmaclength < 0) {
 			logger(LOG_ERR, _("%s (%s) uses bogus MAC length!"), c->name, c->hostname);
+			free(buffer);
 			return false;
 		}
 	} else {
@@ -299,6 +314,7 @@ bool metakey_h(connection_t *c)
 
 	c->allow_request = CHALLENGE;
 
+	free(buffer);
 	return send_challenge(c);
 }
 
@@ -306,6 +322,7 @@ bool send_challenge(connection_t *c)
 {
 	char *buffer;
 	int len;
+	bool ret;
 
 	cp();
 
@@ -315,7 +332,7 @@ bool send_challenge(connection_t *c)
 
 	/* Allocate buffers for the challenge */
 
-	buffer = alloca(2 * len + 1);
+	buffer = xmalloc_and_zero(2 * len + 1);
 
 	if(!c->hischallenge)
 		c->hischallenge = xmalloc(len);
@@ -331,29 +348,37 @@ bool send_challenge(connection_t *c)
 
 	/* Send the challenge */
 
-	return send_request(c, "%d %s", CHALLENGE, buffer);
+	ret = send_request(c, "%d %s", CHALLENGE, buffer);
+
+	free(buffer);
+
+	return ret;
 }
 
 bool challenge_h(connection_t *c)
 {
-	char buffer[MAX_STRING_SIZE];
-	int len;
+	char *buffer, fmt[513];
+	int len = RSA_size(myself->connection->rsa_key);
 
 	cp();
 
-	if(sscanf(c->buffer, "%*d " MAX_STRING, buffer) != 1) {
+	buffer = xmalloc(2 * len + 1);
+	memset(fmt, 0, 513);
+	snprintf(fmt, 512, "%%*d %%%ds", 2*len);
+
+	if(sscanf(c->buffer, fmt, buffer) != 1) {
 		logger(LOG_ERR, _("Got bad %s from %s (%s)"), "CHALLENGE", c->name,
 			   c->hostname);
+		free(buffer);
 		return false;
 	}
 
-	len = RSA_size(myself->connection->rsa_key);
-
 	/* Check if the length of the challenge is all right */
 
 	if(strlen(buffer) != len * 2) {
 		logger(LOG_ERR, _("Possible intruder %s (%s): %s"), c->name,
 			   c->hostname, "wrong challenge length");
+		free(buffer);
 		return false;
 	}
 
@@ -370,6 +395,7 @@ bool challenge_h(connection_t *c)
 
 	/* Rest is done by send_chal_reply() */
 
+	free(buffer);
 	return send_chal_reply(c);
 }
 
