Created
December 27, 2016 00:07
-
-
Save 131/2a5ffedc2acf61061cf39e966def2ff2 to your computer and use it in GitHub Desktop.
Apache ProxyRemote with Proxy-Authorization (over connect/HTTPS)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Index: mod_proxy.c | |
=================================================================== | |
--- mod_proxy.c (revision 1205172) | |
+++ mod_proxy.c (working copy) | |
@@ -965,7 +965,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) { | |
@@ -1016,7 +1017,7 @@ | |
"Running scheme %s handler (attempt %d)", | |
scheme, 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) { | |
@@ -1210,7 +1211,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; | |
@@ -1218,6 +1219,7 @@ | |
r = apr_pstrdup(cmd->pool, r1); | |
scheme = apr_pstrdup(cmd->pool, r1); | |
f = apr_pstrdup(cmd->pool, f1); | |
+ // http://host:port | |
p = strchr(r, ':'); | |
if (p == NULL || p[1] != '/' || p[2] != '/' || p[3] == '\0') { | |
if (regex) | |
@@ -1226,10 +1228,27 @@ | |
return "ProxyRemote: Bad syntax for a remote proxy server"; | |
} | |
else { | |
- scheme[p-r] = 0; | |
+ scheme[p-r] = '\0'; | |
} | |
- q = strchr(p + 3, ':'); | |
+ | |
+ *p = '\0'; /* terminate r (scheme) */ | |
+ p+=3; | |
+ /* may extract authentication string */ | |
+ q = strchr(p, '@'); | |
if (q != NULL) { | |
+ *q = '\0'; | |
+ a = ap_pbase64encode(cmd->pool, p); | |
+ p = q; | |
+ p+=1; | |
+ } | |
+ else | |
+ a = NULL; | |
+ | |
+ /* may extract port */ | |
+ q = strchr(p, ':'); | |
+ | |
+ | |
+ if (q != NULL) { | |
if (sscanf(q + 1, "%u", &port) != 1 || port > 65535) { | |
if (regex) | |
return "ProxyRemoteMatch: Bad syntax for a remote proxy server (bad port number)"; | |
@@ -1240,7 +1259,8 @@ | |
} | |
else | |
port = -1; | |
- *p = '\0'; | |
+ | |
+ | |
if (regex) { | |
reg = ap_pregcomp(cmd->pool, f, AP_REG_EXTENDED); | |
if (!reg) | |
@@ -1249,7 +1269,7 @@ | |
else | |
if (strchr(f, ':') == NULL) | |
ap_str_tolower(f); /* lowercase scheme */ | |
- ap_str_tolower(p + 3); /* lowercase hostname */ | |
+ ap_str_tolower(p ); /* lowercase hostname */ | |
if (port == -1) { | |
port = apr_uri_port_of_scheme(scheme); | |
@@ -1258,8 +1278,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; | |
@@ -2398,8 +2419,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) | |
Index: mod_proxy.h | |
=================================================================== | |
--- mod_proxy.h (revision 1205172) | |
+++ mod_proxy.h (working copy) | |
@@ -104,6 +104,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(<proxyuser>:<proxypasswd>) */ | |
apr_port_t port; /* the port for this proxy */ | |
ap_regex_t *regexp; /* compiled regex (if any) for the remote */ | |
int use_regex; /* simple boolean. True if we have a regex pattern */ | |
@@ -437,7 +438,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)) | |
@@ -641,6 +644,13 @@ | |
proxy_server_conf *conf); | |
/** | |
+ * Request status function | |
+ * @param status status of proxy request | |
+ * @return OK or DECLINED | |
+ */ | |
+ PROXY_DECLARE(int) ap_proxy_request_status(int *status, request_rec *r); | |
+ | |
+/** | |
* Deternime backend hostname and port | |
* @param p memory pool used for processing | |
* @param r current request | |
Index: mod_proxy_connect.c | |
=================================================================== | |
--- mod_proxy_connect.c (revision 1205172) | |
+++ mod_proxy_connect.c (working copy) | |
@@ -75,7 +75,9 @@ | |
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 | |
+ ) | |
{ | |
apr_pool_t *p = r->pool; | |
apr_socket_t *sock; | |
@@ -230,6 +232,16 @@ | |
nbytes = apr_snprintf(buffer, sizeof(buffer), | |
"CONNECT %s HTTP/1.0" CRLF, r->uri); | |
apr_socket_send(sock, buffer, &nbytes); | |
+ | |
+ | |
+ if (proxyauth) { | |
+ nbytes = apr_snprintf(buffer, sizeof(buffer), | |
+ "Proxy-Authorization: Basic %s" CRLF, | |
+ proxyauth); | |
+ apr_socket_send(sock, buffer, &nbytes); | |
+ } | |
+ | |
+ | |
nbytes = apr_snprintf(buffer, sizeof(buffer), | |
"Proxy-agent: %s" CRLF CRLF, ap_get_server_banner()); | |
apr_socket_send(sock, buffer, &nbytes); | |
Index: mod_proxy_http.c | |
=================================================================== | |
--- mod_proxy_http.c (revision 1205172) | |
+++ mod_proxy_http.c (working copy) | |
@@ -687,7 +687,8 @@ | |
proxy_conn_rec *p_conn, conn_rec *origin, | |
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; | |
@@ -927,6 +928,14 @@ | |
APR_BRIGADE_INSERT_TAIL(header_brigade, e); | |
} | |
+ 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); | |
@@ -1922,7 +1931,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]; | |
@@ -2029,7 +2038,8 @@ | |
/* Step Four: Send the Request */ | |
if ((status = ap_proxy_http_request(p, r, backend, backend->connection, | |
- conf, uri, url, server_portstr)) != OK) | |
+ conf, uri, url, server_portstr, (is_ssl ? NULL : proxyauth) | |
+ )) != OK) | |
goto cleanup; | |
/* Step Five: Receive the Response */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment