[PATCH] Initial work on automatically reallocated buffer size for CSD script

Adam Piątyszek ediap at users.sourceforge.net
Thu Feb 11 18:39:27 EST 2010


Signed-off-by: Adam Piątyszek <ediap at users.sourceforge.net>
---
 http.c |   45 +++++++++++++++++++++++++++++++++++----------
 1 files changed, 35 insertions(+), 10 deletions(-)

diff --git a/http.c b/http.c
index d653aff..6eda4e7 100644
--- a/http.c
+++ b/http.c
@@ -155,9 +155,9 @@ static int process_http_response(struct openconnect_info *vpninfo, int *result,
 		}
 		if (!strcasecmp(buf, "Content-Length")) {
 			bodylen = atoi(colon);
-			if (bodylen < 0 || bodylen > buf_len) {
-				vpninfo->progress(vpninfo, PRG_ERR, "Response body too large for buffer (%d > %d)\n",
-					bodylen, buf_len);
+			if (bodylen < 0) {
+				vpninfo->progress(vpninfo, PRG_ERR, "Response body has negative size (%d)\n",
+						  bodylen);
 				return -EINVAL;
 			}
 		}
@@ -203,6 +203,12 @@ static int process_http_response(struct openconnect_info *vpninfo, int *result,
 
 	/* If we were given Content-Length, it's nice and easy... */
 	if (bodylen > 0) {
+		while (bodylen > buf_len) {
+			buf_len *= 2;
+			body = (char*) realloc(body, buf_len);
+			if (!body)
+				return -ENOMEM;
+		}
 		while (done < bodylen) {
 			i = SSL_read(vpninfo->https_ssl, body + done, bodylen - done);
 			if (i < 0) {
@@ -282,7 +288,7 @@ static int fetch_config(struct openconnect_info *vpninfo, char *fu, char *bu,
 			char *server_sha1)
 {
 	struct vpn_option *opt;
-	char buf[MAX_BUF_LEN];
+	char* buf = (char*) calloc(MAX_BUF_LEN, sizeof(char));
 	int result, buflen;
 	unsigned char local_sha1_bin[SHA_DIGEST_LENGTH];
 	char local_sha1_ascii[(SHA_DIGEST_LENGTH * 2)+1];
@@ -308,12 +314,14 @@ static int fetch_config(struct openconnect_info *vpninfo, char *fu, char *bu,
 	buflen = process_http_response(vpninfo, &result, NULL, buf, MAX_BUF_LEN);
 	if (buflen < 0) {
 		/* We'll already have complained about whatever offended us */
+		free(buf);
 		return -EINVAL;
 	}
 
-	if (result != 200)
+	if (result != 200) {
+		free(buf);
 		return -EINVAL;
-
+	}
 
 	EVP_MD_CTX_init(&c);
 	EVP_Digest(buf, buflen, local_sha1_bin, NULL, EVP_sha1(), NULL);
@@ -324,6 +332,7 @@ static int fetch_config(struct openconnect_info *vpninfo, char *fu, char *bu,
 
 	if (strcasecmp(server_sha1, local_sha1_ascii)) {
 		vpninfo->progress(vpninfo, PRG_ERR, "Downloaded config file did not match intended SHA1\n");
+		free(buf);
 		return -EINVAL;
 	}
 
@@ -355,7 +364,13 @@ static int run_csd_script(struct openconnect_info *vpninfo, char *buf, int bufle
 				  strerror(errno));
 		return err;
 	}
-	write(fd, buf, buflen);
+	int write_status = write(fd, buf, buflen);
+	if (write_status < 0) {
+		int err = -errno;
+		vpninfo->progress(vpninfo, PRG_ERR, "Failed to write temporary CSD script file: %s\n",
+				  strerror(errno));
+		return err;
+	}
 	fchmod(fd, 0755);
 	close(fd);
 
@@ -533,7 +548,7 @@ int parse_url(char *url, char **res_proto, char **res_host, int *res_port,
 int openconnect_obtain_cookie(struct openconnect_info *vpninfo)
 {
 	struct vpn_option *opt, *next;
-	char buf[MAX_BUF_LEN];
+	char* buf = (char*) calloc(MAX_BUF_LEN, sizeof(char));
 	int result, buflen;
 	char request_body[2048];
 	char *request_body_type = NULL;
@@ -543,6 +558,7 @@ int openconnect_obtain_cookie(struct openconnect_info *vpninfo)
 	if (!vpninfo->https_ssl && openconnect_open_https(vpninfo)) {
 		vpninfo->progress(vpninfo, PRG_ERR, "Failed to open HTTPS connection to %s\n",
 			vpninfo->hostname);
+		free(buf);
 		return -EINVAL;
 	}
 
@@ -591,6 +607,7 @@ int openconnect_obtain_cookie(struct openconnect_info *vpninfo)
 	buflen = process_http_response(vpninfo, &result, NULL, buf, MAX_BUF_LEN);
 	if (buflen < 0) {
 		/* We'll already have complained about whatever offended us */
+		free(buf);
 		exit(1);
 	}
 
@@ -610,6 +627,7 @@ int openconnect_obtain_cookie(struct openconnect_info *vpninfo)
 				vpninfo->progress(vpninfo, PRG_ERR, "Failed to parse redirected URL '%s': %s\n",
 						  vpninfo->redirect_url, strerror(-ret));
 				free(vpninfo->redirect_url);
+				free(buf);
 				return ret;
 			}
 
@@ -653,6 +671,7 @@ int openconnect_obtain_cookie(struct openconnect_info *vpninfo)
 		} else {
 			vpninfo->progress(vpninfo, PRG_ERR, "Relative redirect (to '%s') not supported\n",
 				vpninfo->redirect_url);
+			free(buf);
 			return -EINVAL;
 		}
 	}
@@ -660,8 +679,10 @@ int openconnect_obtain_cookie(struct openconnect_info *vpninfo)
 	if (vpninfo->csd_stuburl) {
 		/* This is the CSD stub script, which we now need to run */
 		result = run_csd_script(vpninfo, buf, buflen);
-		if (result)
+		if (result) {
+			free(buf);
 			return result;
+		}
 
 		/* Now we'll be redirected to the waiturl */
 		goto retry;
@@ -675,6 +696,7 @@ int openconnect_obtain_cookie(struct openconnect_info *vpninfo)
 			goto retry;
 		}
 		vpninfo->progress(vpninfo, PRG_ERR, "Unknown response from server\n");
+		free(buf);
 		return -EINVAL;
 	}
 	request_body[0] = 0;
@@ -683,8 +705,10 @@ int openconnect_obtain_cookie(struct openconnect_info *vpninfo)
 	if (!result)
 		goto redirect;
 
-	if (result != 2)
+	if (result != 2) {
+		free(buf);
 		return result;
+	}
 	/* A return value of 2 means the XML form indicated
 	   success. We _should_ have a cookie... */
 
@@ -776,6 +800,7 @@ static int proxy_write(int fd, unsigned char *buf, size_t len)
 
 		count += i;
 	}
+	free(buf);
 	return 0;
 }
 
-- 
1.6.6.1




More information about the openconnect-devel mailing list