[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