Author: des
Date: Fri Oct 16 12:21:44 2015
New Revision: 289419
URL: https://svnweb.freebsd.org/changeset/base/289419

Log:
  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 <f...@fabiankeil.de>
  MFC after:    1 week

Modified:
  head/lib/libfetch/http.c

Modified: head/lib/libfetch/http.c
==============================================================================
--- head/lib/libfetch/http.c    Fri Oct 16 12:16:35 2015        (r289418)
+++ head/lib/libfetch/http.c    Fri Oct 16 12:21:44 2015        (r289419)
@@ -1376,8 +1376,12 @@ http_connect(struct url *URL, struct url
 {
        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
        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
                    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;
                }
-               http_get_reply(conn);
+               /* Read and discard the rest of the proxy response */
+               if (fetch_getln(conn) < 0) {
+                       fetch_syserr();
+                       goto ouch;
+               }
+               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
                /* 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 *
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to