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