summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authordes <des@FreeBSD.org>2015-10-16 12:21:44 +0000
committerdes <des@FreeBSD.org>2015-10-16 12:21:44 +0000
commit7cd58b9488563c5becfc657f8fdc56f141ae9aec (patch)
tree8868fc562d1b24540e135a75c5d571150285e715 /lib
parent7f5fdd9fd0fe05175bb9505518308a90bbe9674c (diff)
downloadFreeBSD-src-7cd58b9488563c5becfc657f8fdc56f141ae9aec.zip
FreeBSD-src-7cd58b9488563c5becfc657f8fdc56f141ae9aec.tar.gz
Fix two bugs in HTTPS tunnelling:
- If the proxy returns a non-200 result, set the error code accordingly so the caller / user gets a somewhat meaningful error message. - Consume and discard any HTTP response header following the result line. PR: 194483 Tested by: Fabian Keil <fk@fabiankeil.de> MFC after: 1 week
Diffstat (limited to 'lib')
-rw-r--r--lib/libfetch/http.c36
1 files changed, 32 insertions, 4 deletions
diff --git a/lib/libfetch/http.c b/lib/libfetch/http.c
index 91ca6a3..f6a7454 100644
--- a/lib/libfetch/http.c
+++ b/lib/libfetch/http.c
@@ -1376,8 +1376,12 @@ http_connect(struct url *URL, struct url *purl, const char *flags)
{
struct url *curl;
conn_t *conn;
+ hdr_t h;
+ http_headerbuf_t headerbuf;
+ const char *p;
int verbose;
int af, val;
+ int serrno;
#ifdef INET6
af = AF_UNSPEC;
@@ -1398,6 +1402,7 @@ http_connect(struct url *URL, struct url *purl, const char *flags)
if ((conn = fetch_connect(curl->host, curl->port, af, verbose)) == NULL)
/* fetch_connect() has already set an error code */
return (NULL);
+ init_http_headerbuf(&headerbuf);
if (strcasecmp(URL->scheme, SCHEME_HTTPS) == 0 && purl) {
http_cmd(conn, "CONNECT %s:%d HTTP/1.1",
URL->host, URL->port);
@@ -1405,10 +1410,26 @@ http_connect(struct url *URL, struct url *purl, const char *flags)
URL->host, URL->port);
http_cmd(conn, "");
if (http_get_reply(conn) != HTTP_OK) {
- fetch_close(conn);
- return (NULL);
+ http_seterr(conn->err);
+ goto ouch;
+ }
+ /* Read and discard the rest of the proxy response */
+ if (fetch_getln(conn) < 0) {
+ fetch_syserr();
+ goto ouch;
}
- http_get_reply(conn);
+ do {
+ switch ((h = http_next_header(conn, &headerbuf, &p))) {
+ case hdr_syserror:
+ fetch_syserr();
+ goto ouch;
+ case hdr_error:
+ http_seterr(HTTP_PROTOCOL_ERROR);
+ goto ouch;
+ default:
+ /* ignore */ ;
+ }
+ } while (h < hdr_end);
}
if (strcasecmp(URL->scheme, SCHEME_HTTPS) == 0 &&
fetch_ssl(conn, URL, verbose) == -1) {
@@ -1416,13 +1437,20 @@ http_connect(struct url *URL, struct url *purl, const char *flags)
/* grrr */
errno = EAUTH;
fetch_syserr();
- return (NULL);
+ goto ouch;
}
val = 1;
setsockopt(conn->sd, IPPROTO_TCP, TCP_NOPUSH, &val, sizeof(val));
+ clean_http_headerbuf(&headerbuf);
return (conn);
+ouch:
+ serrno = errno;
+ clean_http_headerbuf(&headerbuf);
+ fetch_close(conn);
+ errno = serrno;
+ return (NULL);
}
static struct url *
OpenPOWER on IntegriCloud