You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by jo...@apache.org on 2020/09/17 11:31:43 UTC

svn commit: r1881790 - in /httpd/httpd/trunk: changes-entries/pr37355.txt docs/manual/mod/mod_proxy.xml modules/proxy/mod_proxy.c modules/proxy/mod_proxy.h modules/proxy/proxy_util.c

Author: jorton
Date: Thu Sep 17 11:31:43 2020
New Revision: 1881790

URL: http://svn.apache.org/viewvc?rev=1881790&view=rev
Log:
mod_proxy: Add support for an optional third argument to ProxyRemote*
to configure the Basic auth credentials to send to the remote proxy.

(Note that credentials are always sent w/o waiting for a challenge as
with proxy-chain-auth, and only Basic is supported - both of which are
not exactly ideal - but better than nothing.)

* modules/proxy/mod_proxy.h (struct proxy_remote): Add creds field.

* modules/proxy/mod_proxy.c (proxy_handler): Pass forward proxy
  credentials via r->notes.
  (add_proxy): Take credentials and base64-encode into ->creds field if
  passed.
  (add_proxy_noregex, add_proxy_regex): Take optional creds argument.

* modules/proxy/proxy_util.c (ap_proxy_determine_connection):
  Use proxy credentials from r->notes if available.
  (ap_proxy_create_hdrbrgd): Set Proxy-Authorization header from
  credentials in r->notes if present.

PR: 37355
Github: closes #135

Added:
    httpd/httpd/trunk/changes-entries/pr37355.txt
Modified:
    httpd/httpd/trunk/docs/manual/mod/mod_proxy.xml
    httpd/httpd/trunk/modules/proxy/mod_proxy.c
    httpd/httpd/trunk/modules/proxy/mod_proxy.h
    httpd/httpd/trunk/modules/proxy/proxy_util.c

Added: httpd/httpd/trunk/changes-entries/pr37355.txt
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/changes-entries/pr37355.txt?rev=1881790&view=auto
==============================================================================
--- httpd/httpd/trunk/changes-entries/pr37355.txt (added)
+++ httpd/httpd/trunk/changes-entries/pr37355.txt Thu Sep 17 11:31:43 2020
@@ -0,0 +1,3 @@
+  *) mod_proxy: Add optional third argument for ProxyRemote, which
+     configures Basic authentication credentials to pass to the remote
+     proxy.  PR 37355.  [Joe Orton]

Modified: httpd/httpd/trunk/docs/manual/mod/mod_proxy.xml
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/manual/mod/mod_proxy.xml?rev=1881790&r1=1881789&r2=1881790&view=diff
==============================================================================
--- httpd/httpd/trunk/docs/manual/mod/mod_proxy.xml (original)
+++ httpd/httpd/trunk/docs/manual/mod/mod_proxy.xml Thu Sep 17 11:31:43 2020
@@ -671,9 +671,10 @@ context in 2.3.3 and later.</compatibili
 <directivesynopsis>
 <name>ProxyRemote</name>
 <description>Remote proxy used to handle certain requests</description>
-<syntax>ProxyRemote <var>match</var> <var>remote-server</var></syntax>
+<syntax>ProxyRemote <var>match</var> <var>remote-server</var> [<var>username:password</var>]</syntax>
 <contextlist><context>server config</context><context>virtual host</context>
 </contextlist>
+<compatibility>The optional third argument is usable only in httpd 2.5.1 and later.</compatibility>
 
 <usage>
     <p>This defines remote proxies to this proxy. <var>match</var> is either the
@@ -707,6 +708,15 @@ ProxyRemote ftp http://ftpproxy.mydomain
     <p>This option also supports reverse proxy configuration; a backend
     webserver can be embedded within a virtualhost URL space even if that
     server is hidden by another forward proxy.</p>
+
+    <p>An optional third argument <var>username:password</var> may be
+    given, which defines the Basic authentication credentials to pass
+    to the configured remote proxy.  The credentials will always be
+    sent without first waiting for the remote proxy to send a Basic
+    authentication challenge.  The <a
+    href="mod_proxy_http.html#env">Proxy-Chain-Auth</a> environment
+    variable has no effect if this argument is used.</p>
+
 </usage>
 </directivesynopsis>
 

Modified: httpd/httpd/trunk/modules/proxy/mod_proxy.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/proxy/mod_proxy.c?rev=1881790&r1=1881789&r2=1881790&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/proxy/mod_proxy.c (original)
+++ httpd/httpd/trunk/modules/proxy/mod_proxy.c Thu Sep 17 11:31:43 2020
@@ -1461,11 +1461,20 @@ static int proxy_handler(request_rec *r)
                     /* handle the scheme */
                     ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01142)
                                   "Trying to run scheme_handler against proxy");
+
+                    if (ents[i].creds) {
+                        apr_table_set(r->notes, "proxy-basic-creds", ents[i].creds);
+                        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
+                                      "Using proxy auth creds %s", ents[i].creds);
+                    }
+
                     access_status = proxy_run_scheme_handler(r, worker,
                                                              conf, url,
                                                              ents[i].hostname,
                                                              ents[i].port);
 
+                    if (ents[i].creds) apr_table_unset(r->notes, "proxy-basic-creds");
+
                     /* Did the scheme handler process the request? */
                     if (access_status != DECLINED) {
                         const char *cl_a;
@@ -1917,8 +1926,8 @@ static void *merge_proxy_dir_config(apr_
     return new;
 }
 
-static const char *
-    add_proxy(cmd_parms *cmd, void *dummy, const char *f1, const char *r1, int regex)
+static const char *add_proxy(cmd_parms *cmd, void *dummy, const char *f1,
+                             const char *r1, const char *creds, int regex)
 {
     server_rec *s = cmd->server;
     proxy_server_conf *conf =
@@ -1976,19 +1985,24 @@ static const char *
     new->port = port;
     new->regexp = reg;
     new->use_regex = regex;
+    if (creds) {
+        new->creds = apr_pstrcat(cmd->pool, "Basic ",
+                                 ap_pbase64encode(cmd->pool, (char *)creds),
+                                 NULL);
+    }
     return NULL;
 }
 
-static const char *
-    add_proxy_noregex(cmd_parms *cmd, void *dummy, const char *f1, const char *r1)
+static const char *add_proxy_noregex(cmd_parms *cmd, void *dummy, const char *f1,
+                                     const char *r1, const char *creds)
 {
-    return add_proxy(cmd, dummy, f1, r1, 0);
+    return add_proxy(cmd, dummy, f1, r1, creds, 0);
 }
 
-static const char *
-    add_proxy_regex(cmd_parms *cmd, void *dummy, const char *f1, const char *r1)
+static const char *add_proxy_regex(cmd_parms *cmd, void *dummy, const char *f1,
+                                   const char *r1, const char *creds)
 {
-    return add_proxy(cmd, dummy, f1, r1, 1);
+    return add_proxy(cmd, dummy, f1, r1, creds, 1);
 }
 
 PROXY_DECLARE(const char *) ap_proxy_de_socketfy(apr_pool_t *p, const char *url)
@@ -3046,9 +3060,9 @@ static const command_rec proxy_cmds[] =
     "location, in regular expression syntax"),
     AP_INIT_FLAG("ProxyRequests", set_proxy_req, NULL, RSRC_CONF,
      "on if the true proxy requests should be accepted"),
-    AP_INIT_TAKE2("ProxyRemote", add_proxy_noregex, NULL, RSRC_CONF,
+    AP_INIT_TAKE23("ProxyRemote", add_proxy_noregex, NULL, RSRC_CONF,
      "a scheme, partial URL or '*' and a proxy server"),
-    AP_INIT_TAKE2("ProxyRemoteMatch", add_proxy_regex, NULL, RSRC_CONF,
+    AP_INIT_TAKE23("ProxyRemoteMatch", add_proxy_regex, NULL, RSRC_CONF,
      "a regex pattern and a proxy server"),
     AP_INIT_FLAG("ProxyPassInterpolateEnv", ap_set_flag_slot_char,
         (void*)APR_OFFSETOF(proxy_dir_conf, interpolate_env),

Modified: httpd/httpd/trunk/modules/proxy/mod_proxy.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/proxy/mod_proxy.h?rev=1881790&r1=1881789&r2=1881790&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/proxy/mod_proxy.h (original)
+++ httpd/httpd/trunk/modules/proxy/mod_proxy.h Thu Sep 17 11:31:43 2020
@@ -116,6 +116,7 @@ struct proxy_remote {
     const char *protocol;   /* the scheme used to talk to this proxy */
     const char *hostname;   /* the hostname of this proxy */
     ap_regex_t *regexp;     /* compiled regex (if any) for the remote */
+    const char *creds;      /* auth credentials (if any) for the proxy */
     int use_regex;          /* simple boolean. True if we have a regex pattern */
     apr_port_t  port;       /* the port for this proxy */
 };

Modified: httpd/httpd/trunk/modules/proxy/proxy_util.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/proxy/proxy_util.c?rev=1881790&r1=1881789&r2=1881790&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/proxy/proxy_util.c (original)
+++ httpd/httpd/trunk/modules/proxy/proxy_util.c Thu Sep 17 11:31:43 2020
@@ -2562,11 +2562,15 @@ ap_proxy_determine_connection(apr_pool_t
                      * So let's make it configurable by env.
                      * The logic here is the same used in mod_proxy_http.
                      */
-                    proxy_auth = apr_table_get(r->headers_in, "Proxy-Authorization");
+                    proxy_auth = apr_table_get(r->notes, "proxy-basic-creds");
+                    if (proxy_auth == NULL)
+                        proxy_auth = apr_table_get(r->headers_in, "Proxy-Authorization");
+
                     if (proxy_auth != NULL &&
                         proxy_auth[0] != '\0' &&
-                        (r->user == NULL || /* we haven't yet authenticated */
-                        apr_table_get(r->subprocess_env, "Proxy-Chain-Auth"))) {
+                        (r->user == NULL /* we haven't yet authenticated */
+                         || apr_table_get(r->subprocess_env, "Proxy-Chain-Auth")
+                         || apr_table_get(r->notes, "proxy-basic-creds"))) {
                         forward->proxy_auth = apr_pstrdup(conn->pool, proxy_auth);
                     }
                 }
@@ -2798,7 +2802,8 @@ static apr_status_t send_http_connect(pr
     nbytes = apr_snprintf(buffer, sizeof(buffer),
                           "CONNECT %s:%d HTTP/1.0" CRLF,
                           forward->target_host, forward->target_port);
-    /* Add proxy authorization from the initial request if necessary */
+    /* Add proxy authorization from the configuration, or initial
+     * request if necessary */
     if (forward->proxy_auth != NULL) {
         nbytes += apr_snprintf(buffer + nbytes, sizeof(buffer) - nbytes,
                                "Proxy-Authorization: %s" CRLF,
@@ -3741,7 +3746,7 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbr
     apr_bucket *e;
     int do_100_continue;
     conn_rec *origin = p_conn->connection;
-    const char *fpr1;
+    const char *fpr1, *creds;
     proxy_dir_conf *dconf = ap_get_module_config(r->per_dir_config, &proxy_module);
 
     /*
@@ -3920,6 +3925,11 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbr
         return HTTP_BAD_REQUEST;
     }
 
+    creds = apr_table_get(r->notes, "proxy-basic-creds");
+    if (creds) {
+        apr_table_mergen(r->headers_in, "Proxy-Authorization", creds);
+    }
+
     /* send request headers */
     headers_in_array = apr_table_elts(r->headers_in);
     headers_in = (const apr_table_entry_t *) headers_in_array->elts;