From: Daniel Lenski Date: Wed, 29 Nov 2017 08:49:16 +0000 (-0800) Subject: Loop when sending HTTP requests larger than the 16KiB SSL record max X-Git-Tag: v8.00~130 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=2d77040a870851a625de16938fcdda6a5494d7ed;p=users%2Fdwmw2%2Fopenconnect.git Loop when sending HTTP requests larger than the 16KiB SSL record max A single SSL record can't contain >16KiB, so the HTTPS request buffer may not get fully written if it's larger than this. I discovered this frustrating bug while working on GlobalProtect HIP support, which requires sending giant blobs of XML to the gateway. Signed-off-by: Daniel Lenski Signed-off-by: David Woodhouse --- diff --git a/http.c b/http.c index 59f93e50..e53f3fce 100644 --- a/http.c +++ b/http.c @@ -818,7 +818,7 @@ int do_https_request(struct openconnect_info *vpninfo, const char *method, int result; int rq_retry; int rlen, pad; - int auth = 0; + int i, auth = 0; int max_redirects = 10; if (request_body_type && buf_error(request_body)) @@ -913,17 +913,22 @@ int do_https_request(struct openconnect_info *vpninfo, const char *method, if (vpninfo->dump_http_traffic) dump_buf(vpninfo, '>', buf->data); - result = vpninfo->ssl_write(vpninfo, buf->data, buf->pos); - if (rq_retry && result < 0) { - openconnect_close_https(vpninfo, 0); - goto retry; + for (i = 0; i < buf->pos; i += 16384) { + result = vpninfo->ssl_write(vpninfo, buf->data + i, MIN(buf->pos - i, 16384) ); + if (result < 0) { + if (rq_retry) { + /* Retry if we failed to send the request on + an already-open connection */ + openconnect_close_https(vpninfo, 0); + goto retry; + } + /* We'll already have complained about whatever offended us */ + goto out; + } } - if (result < 0) - goto out; result = process_http_response(vpninfo, 0, http_auth_hdrs, buf); if (result < 0) { - /* We'll already have complained about whatever offended us */ goto out; } if (vpninfo->dump_http_traffic && buf->pos) diff --git a/openconnect-internal.h b/openconnect-internal.h index b70085d2..5b9a8d6c 100644 --- a/openconnect-internal.h +++ b/openconnect-internal.h @@ -122,6 +122,9 @@ #ifndef MAX #define MAX(x,y) ((x)>(y))?(x):(y) #endif +#ifndef MIN +#define MIN(x,y) ((x)<(y))?(x):(y) +#endif /****************************************************************************/ struct pkt {