]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[MEDIUM] http: add support for proxy authentication
authorWilly Tarreau <w@1wt.eu>
Sun, 31 Jan 2010 20:46:18 +0000 (21:46 +0100)
committerWilly Tarreau <w@1wt.eu>
Sun, 31 Jan 2010 20:46:18 +0000 (21:46 +0100)
We're already able to know if a request is a proxy request or a
normal one, and we have an option "http-use-proxy-header" which states
that proxy headers must be checked. So let's switch to use the proxy
authentication headers and responses when this option is set and we're
facing a proxy request. That allows haproxy to enforce auth in front
of a proxy.

doc/configuration.txt
src/proto_http.c

index 2ef3639eade2341f6489fd2d5a5e9d5dbdb48a99..48c90c763dd5b602760ebfc9d72e58713097d7df 100644 (file)
@@ -2691,6 +2691,11 @@ option http-use-proxy-header
   that this option can only be specified in a frontend and will affect the
   request along its whole life.
 
+  Also, when this option is set, a request which requires authentication will
+  automatically switch to use proxy authentication headers if it is itself a
+  proxied request. That makes it possible to check or enforce authentication in
+  front of an existing proxy.
+
   This option should normally never be used, except in front of a proxy.
 
   See also : "option httpclose", "option forceclose" and "option
index 4ac53b38deea2eb4ee1bfa343f8d9c8c880acb3d..1b59c68f5f2f5f71a96b8c5e469e771a3fb2c473 100644 (file)
@@ -111,6 +111,15 @@ const char *HTTP_401_fmt =
        "\r\n"
        "<html><body><h1>401 Unauthorized</h1>\nYou need a valid user and password to access this content.\n</body></html>\n";
 
+const char *HTTP_407_fmt =
+       "HTTP/1.0 407 Unauthorized\r\n"
+       "Cache-Control: no-cache\r\n"
+       "Connection: close\r\n"
+       "Content-Type: text/html\r\n"
+       "Proxy-Authenticate: Basic realm=\"%s\"\r\n"
+       "\r\n"
+       "<html><body><h1>401 Unauthorized</h1>\nYou need a valid user and password to access this content.\n</body></html>\n";
+
 
 const int http_err_codes[HTTP_ERR_SIZE] = {
        [HTTP_ERR_400] = 400,
@@ -1507,7 +1516,16 @@ get_http_auth(struct session *s)
        txn->auth.method = HTTP_AUTH_WRONG;
 
        ctx.idx = 0;
-       if (!http_find_header("Authorization", txn->req.sol, &txn->hdr_idx, &ctx))
+
+       if (txn->flags & TX_USE_PX_CONN) {
+               h = "Proxy-Authorization";
+               len = strlen(h);
+       } else {
+               h = "Authorization";
+               len = strlen(h);
+       }
+
+       if (!http_find_header2(h, len, txn->req.sol, &txn->hdr_idx, &ctx))
                return 0;
 
        h = ctx.line + ctx.val;
@@ -2969,7 +2987,7 @@ int http_process_req_common(struct session *s, struct buffer *req, int an_bit, s
                if (!realm)
                        realm = do_stats?STATS_DEFAULT_REALM:px->id;
 
-               sprintf(trash, HTTP_401_fmt, realm);
+               sprintf(trash, (txn->flags & TX_USE_PX_CONN) ? HTTP_407_fmt : HTTP_401_fmt, realm);
                chunk_initlen(&msg, trash, sizeof(trash), strlen(trash));
                txn->status = 401;
                stream_int_retnclose(req->prod, &msg);