--- modules/proxy/mod_proxy.h.orig 2013-07-11 14:21:19.000000000 +0200 +++ modules/proxy/mod_proxy.h.orig 2013-12-13 17:27:11.000000000 +0100 @@ -99,6 +99,7 @@ const char *scheme; /* the schemes handled by this proxy, or '*' */ const char *protocol; /* the scheme used to talk to this proxy */ const char *hostname; /* the hostname of this proxy */ + const char *auth; /* base64encode(:) */ ap_regex_t *regexp; /* compiled regex (if any) for the remote */ int use_regex; /* simple boolean. True if we have a regex pattern */ apr_port_t port; /* the port for this proxy */ @@ -494,7 +495,9 @@ APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, scheme_handler, (request_rec *r, proxy_worker *worker, proxy_server_conf *conf, char *url, - const char *proxyhost, apr_port_t proxyport)) + const char *proxyhost, apr_port_t proxyport, + const char *proxyauth)) + APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, canon_handler, (request_rec *r, char *url)) @@ -776,6 +779,7 @@ * @param url request url * @param proxyname are we connecting directly or via a proxy * @param proxyport proxy host port + * @param proxyauth proxy authentication * @param server_portstr Via headers server port * @param server_portstr_size size of the server_portstr buffer * @return OK or HTTP_XXX error @@ -788,6 +792,7 @@ char **url, const char *proxyname, apr_port_t proxyport, + const char *proxyauth, char *server_portstr, int server_portstr_size); --- modules/proxy/mod_proxy_ajp.c.orig 2012-08-17 16:54:18.000000000 +0200 +++ modules/proxy/mod_proxy_ajp.c.orig 2013-11-20 10:56:37.000000000 +0100 @@ -691,7 +691,8 @@ static int proxy_ajp_handler(request_rec *r, proxy_worker *worker, proxy_server_conf *conf, char *url, const char *proxyname, - apr_port_t proxyport) + apr_port_t proxyport, + const char *proxyauth) { int status; char server_portstr[32]; @@ -731,7 +732,8 @@ char *locurl = url; /* Step One: Determine Who To Connect To */ status = ap_proxy_determine_connection(p, r, conf, worker, backend, - uri, &locurl, proxyname, proxyport, + uri, &locurl, + proxyname, proxyport,proxyauth, server_portstr, sizeof(server_portstr)); --- modules/proxy/mod_proxy_connect.c.orig 2013-02-06 18:13:59.000000000 +0100 +++ modules/proxy/mod_proxy_connect.c.orig 2013-11-20 10:22:01.000000000 +0100 @@ -194,7 +194,8 @@ static int proxy_connect_handler(request_rec *r, proxy_worker *worker, proxy_server_conf *conf, char *url, const char *proxyname, - apr_port_t proxyport) + apr_port_t proxyport, + const char *proxyauth) { connect_conf *c_conf = ap_get_module_config(r->server->module_config, &proxy_connect_module); @@ -370,6 +371,15 @@ "sending the CONNECT request to the remote proxy"); ap_fprintf(backconn->output_filters, bb, "CONNECT %s HTTP/1.0" CRLF, r->uri); + + /* add Proxyauth Header if configured + */ + if (proxyauth) { + ap_fprintf(backconn->output_filters, bb, + "Proxy-Authorization: Basic %s" CRLF, + proxyauth); + } + ap_fprintf(backconn->output_filters, bb, "Proxy-agent: %s" CRLF CRLF, ap_get_server_banner()); ap_fflush(backconn->output_filters, bb); --- modules/proxy/mod_proxy.c.orig 2013-07-09 14:35:23.000000000 +0200 +++ modules/proxy/mod_proxy.c.orig 2013-11-20 10:34:30.000000000 +0100 @@ -1048,7 +1048,8 @@ access_status = proxy_run_scheme_handler(r, worker, conf, url, ents[i].hostname, - ents[i].port); + ents[i].port, + ents[i].auth); /* Did the scheme handler process the request? */ if (access_status != DECLINED) { @@ -1100,7 +1101,7 @@ scheme, attempts); AP_PROXY_RUN(r, worker, conf, url, attempts); access_status = proxy_run_scheme_handler(r, worker, conf, - url, NULL, 0); + url, NULL, 0, NULL); if (access_status == OK) break; else if (access_status == HTTP_INTERNAL_SERVER_ERROR) { @@ -1339,7 +1340,7 @@ proxy_server_conf *conf = (proxy_server_conf *) ap_get_module_config(s->module_config, &proxy_module); struct proxy_remote *new; - char *p, *q; + char *p, *q, *a; char *r, *f, *scheme; ap_regex_t *reg = NULL; int port; @@ -1347,6 +1348,10 @@ r = apr_pstrdup(cmd->pool, r1); scheme = apr_pstrdup(cmd->pool, r1); f = apr_pstrdup(cmd->pool, f1); + /* separate different items from remote proxy server configuration + * r = ://[@][:] + */ + /* separate scheme (must) */ p = strchr(r, ':'); if (p == NULL || p[1] != '/' || p[2] != '/' || p[3] == '\0') { if (regex) @@ -1355,9 +1360,26 @@ return "ProxyRemote: Bad syntax for a remote proxy server"; } else { - scheme[p-r] = 0; + scheme[p-r] = '\0'; + } + *p = '\0'; /* terminate r (scheme) */ + p+=3; + /* separate authentication string (optional, default = NULL) */ + q = strchr(p, '@'); + if (q != NULL) { + *q = '\0'; + /* missing: syntax check of the auth string + * but do we really need this? + */ + a = ap_pbase64encode(cmd->pool, p); + p = q; + p+=1; + } + else { + a = NULL; } - q = strchr(p + 3, ':'); + /* separate port (optional, default = default port of scheme) */ + q = strchr(p, ':'); if (q != NULL) { if (sscanf(q + 1, "%u", &port) != 1 || port > 65535) { if (regex) @@ -1367,18 +1389,19 @@ } *q = '\0'; } - else + else { port = -1; - *p = '\0'; + } + if (regex) { reg = ap_pregcomp(cmd->pool, f, AP_REG_EXTENDED); if (!reg) return "Regular expression for ProxyRemoteMatch could not be compiled."; } - else - if (strchr(f, ':') == NULL) - ap_str_tolower(f); /* lowercase scheme */ - ap_str_tolower(p + 3); /* lowercase hostname */ + else if (strchr(f, ':') == NULL) { + ap_str_tolower(f); /* lowercase scheme */ + } + ap_str_tolower(p); /* lowercase hostname */ if (port == -1) { port = apr_uri_port_of_scheme(scheme); @@ -1387,8 +1410,9 @@ new = apr_array_push(conf->proxies); new->scheme = f; new->protocol = r; - new->hostname = p + 3; + new->hostname = p; new->port = port; + new->auth = a; new->regexp = reg; new->use_regex = regex; return NULL; @@ -2292,7 +2316,7 @@ 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, - "a scheme, partial URL or '*' and a proxy server"), + "a scheme, partial URL or '*' and a proxy server optional with auth"), AP_INIT_TAKE2("ProxyRemoteMatch", add_proxy_regex, NULL, RSRC_CONF, "a regex pattern and a proxy server"), AP_INIT_FLAG("ProxyPassInterpolateEnv", ap_set_flag_slot_char, @@ -2655,8 +2679,10 @@ (request_rec *r, proxy_worker *worker, proxy_server_conf *conf, char *url, const char *proxyhost, - apr_port_t proxyport),(r,worker,conf, - url,proxyhost,proxyport),DECLINED) + apr_port_t proxyport, + const char *proxyauth), + (r,worker,conf, + url,proxyhost,proxyport, proxyauth),DECLINED) APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(proxy, PROXY, int, canon_handler, (request_rec *r, char *url),(r, url),DECLINED) --- modules/proxy/mod_proxy_fcgi.c.orig 2012-04-27 15:09:51.000000000 +0200 +++ modules/proxy/mod_proxy_fcgi.c.orig 2013-11-20 10:57:14.000000000 +0100 @@ -925,7 +925,8 @@ static int proxy_fcgi_handler(request_rec *r, proxy_worker *worker, proxy_server_conf *conf, char *url, const char *proxyname, - apr_port_t proxyport) + apr_port_t proxyport, + const char *proxyauth) { int status; char server_portstr[32]; @@ -970,7 +971,8 @@ /* Step One: Determine Who To Connect To */ status = ap_proxy_determine_connection(p, r, conf, worker, backend, - uri, &url, proxyname, proxyport, + uri, &url, + proxyname, proxyport, proxyauth, server_portstr, sizeof(server_portstr)); if (status != OK) { --- modules/proxy/mod_proxy_fdpass.c.orig 2012-04-04 22:11:57.000000000 +0200 +++ modules/proxy/mod_proxy_fdpass.c.orig 2013-11-20 10:25:38.000000000 +0100 @@ -179,7 +179,8 @@ static int proxy_fdpass_handler(request_rec *r, proxy_worker *worker, proxy_server_conf *conf, char *url, const char *proxyname, - apr_port_t proxyport) + apr_port_t proxyport, + const char *proxyauth) { apr_status_t rv; apr_socket_t *sock; --- modules/proxy/mod_proxy_ftp.c.orig 2013-01-07 17:04:56.000000000 +0100 +++ modules/proxy/mod_proxy_ftp.c.orig 2013-11-20 10:20:21.000000000 +0100 @@ -961,7 +961,8 @@ */ static int proxy_ftp_handler(request_rec *r, proxy_worker *worker, proxy_server_conf *conf, char *url, - const char *proxyhost, apr_port_t proxyport) + const char *proxyhost, apr_port_t proxyport, + const char *proxyauth) { apr_pool_t *p = r->pool; conn_rec *c = r->connection; --- modules/proxy/mod_proxy_http.c.orig 2013-07-11 14:21:19.000000000 +0200 +++ modules/proxy/mod_proxy_http.c.orig 2013-12-12 15:35:13.000000000 +0100 @@ -682,7 +682,8 @@ proxy_conn_rec *p_conn, proxy_worker *worker, proxy_server_conf *conf, apr_uri_t *uri, - char *url, char *server_portstr) + char *url, char *server_portstr, + const char *proxyauth) { conn_rec *c = r->connection; apr_bucket_alloc_t *bucket_alloc = c->bucket_alloc; @@ -718,6 +719,14 @@ return rv; } + if (proxyauth) { + buf = apr_pstrcat(p, "Proxy-Authorization: Basic ", + proxyauth, CRLF, NULL); + ap_xlate_proto_to_ascii(buf, strlen(buf)); + e = apr_bucket_pool_create(buf, strlen(buf), p, c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(header_brigade, e); + } + /* We have headers, let's figure out our request body... */ input_brigade = apr_brigade_create(p, bucket_alloc); @@ -1849,7 +1858,7 @@ static int proxy_http_handler(request_rec *r, proxy_worker *worker, proxy_server_conf *conf, char *url, const char *proxyname, - apr_port_t proxyport) + apr_port_t proxyport, const char *proxyauth) { int status; char server_portstr[32]; @@ -1932,7 +1941,7 @@ /* Step One: Determine Who To Connect To */ if ((status = ap_proxy_determine_connection(p, r, conf, worker, backend, uri, &locurl, proxyname, - proxyport, server_portstr, + proxyport, proxyauth, server_portstr, sizeof(server_portstr))) != OK) break; @@ -1977,12 +1986,14 @@ } } + /* Step Four: Send the Request * On the off-chance that we forced a 100-Continue as a * kinda HTTP ping test, allow for retries */ if ((status = ap_proxy_http_request(p, r, backend, worker, - conf, uri, locurl, server_portstr)) != OK) { + conf, uri, locurl, server_portstr, + (is_ssl ? NULL : proxyauth))) != OK) { if ((status == HTTP_SERVICE_UNAVAILABLE) && worker->s->ping_timeout_set) { backend->close = 1; ap_log_rerror(APLOG_MARK, APLOG_INFO, status, r, APLOGNO(01115) --- modules/proxy/mod_proxy_scgi.c.orig 2011-12-05 01:08:01.000000000 +0100 +++ modules/proxy/mod_proxy_scgi.c.orig 2013-11-20 10:57:44.000000000 +0100 @@ -497,7 +497,8 @@ */ static int scgi_handler(request_rec *r, proxy_worker *worker, proxy_server_conf *conf, char *url, - const char *proxyname, apr_port_t proxyport) + const char *proxyname, apr_port_t proxyport, + const char *proxyauth) { int status; proxy_conn_rec *backend = NULL; @@ -521,7 +522,8 @@ /* Step One: Determine Who To Connect To */ status = ap_proxy_determine_connection(p, r, conf, worker, backend, - uri, &url, proxyname, proxyport, + uri, &url, + proxyname, proxyport, proxyauth, &dummy, 1); if (status != OK) { goto cleanup; --- modules/proxy/mod_proxy_wstunnel.c.orig 2013-06-13 17:09:31.000000000 +0200 +++ modules/proxy/mod_proxy_wstunnel.c.orig 2013-11-20 10:58:18.000000000 +0100 @@ -305,7 +305,8 @@ static int proxy_wstunnel_handler(request_rec *r, proxy_worker *worker, proxy_server_conf *conf, char *url, const char *proxyname, - apr_port_t proxyport) + apr_port_t proxyport, + const char *proxyauth) { int status; char server_portstr[32]; @@ -349,7 +350,8 @@ char *locurl = url; /* Step One: Determine Who To Connect To */ status = ap_proxy_determine_connection(p, r, conf, worker, backend, - uri, &locurl, proxyname, proxyport, + uri, &locurl, + proxyname, proxyport, proxyauth, server_portstr, sizeof(server_portstr)); --- modules/proxy/proxy_util.c.orig 2013-07-11 14:21:19.000000000 +0200 +++ modules/proxy/proxy_util.c.orig 2013-12-16 15:43:12.000000000 +0100 @@ -2047,6 +2047,7 @@ char **url, const char *proxyname, apr_port_t proxyport, + const char *proxyauth, char *server_portstr, int server_portstr_size) { @@ -2077,7 +2078,10 @@ * short living pool. */ /* are we connecting directly, or via a proxy? */ - if (!proxyname) { + /* handle HTTP/1.0 via SSL like direct connect */ + if (!proxyname || + (conn->is_ssl && + apr_table_get(r->subprocess_env, "force-proxy-request-1.0"))) { *url = apr_pstrcat(p, uri->path, uri->query ? "?" : "", uri->query ? uri->query : "", uri->fragment ? "#" : "", @@ -2123,8 +2127,12 @@ proxy_auth[0] != '\0' && r->user == NULL && /* we haven't yet authenticated */ apr_table_get(r->subprocess_env, "Proxy-Chain-Auth")) { + /* take ProxyAuth from Request */ forward->proxy_auth = apr_pstrdup(conn->pool, proxy_auth); - } + } else if ( proxyauth ) { + /* take ProxyAuth from ProxyRemote */ + forward->proxy_auth = apr_pstrcat(conn->pool, "Basic ", proxyauth, NULL); + } } } else { @@ -2283,11 +2291,6 @@ forward_info *forward = (forward_info *)backend->forward; int len = 0; - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00948) - "CONNECT: sending the CONNECT request for %s:%d " - "to the remote proxy %pI (%s)", - forward->target_host, forward->target_port, - backend->addr, backend->hostname); /* Create the CONNECT request */ nbytes = apr_snprintf(buffer, sizeof(buffer), "CONNECT %s:%d HTTP/1.0" CRLF, @@ -2297,6 +2300,17 @@ nbytes += apr_snprintf(buffer + nbytes, sizeof(buffer) - nbytes, "Proxy-Authorization: %s" CRLF, forward->proxy_auth); + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00948) + "CONNECT: sending the CONNECT request for %s:%d " + "to the remote proxy %pI (%s) with forward auth \"%s\"", + forward->target_host, forward->target_port, + backend->addr, backend->hostname, forward->proxy_auth); + } else { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00948) + "CONNECT: sending the CONNECT request for %s:%d " + "to the remote proxy %pI (%s) without auth", + forward->target_host, forward->target_port, + backend->addr, backend->hostname); } /* Set a reasonable agent and send everything */ nbytes += apr_snprintf(buffer + nbytes, sizeof(buffer) - nbytes,