Added support for authenticated proxy upstream
This commit is contained in:
parent
cb6f868739
commit
902d5e4698
@ -158,6 +158,9 @@ LogLevel Info
|
||||
# # default upstream is internet firewall
|
||||
# upstream firewall.internal.example.com:80
|
||||
#
|
||||
# # connection through testproxy with authentication
|
||||
# upstream user:password@testproxy:8008 ".test.domain.invalid"
|
||||
#
|
||||
# The LAST matching rule wins the route decision. As you can see, you
|
||||
# can use a host, or a domain:
|
||||
# name matches host exactly
|
||||
|
42
src/conf.c
42
src/conf.c
@ -47,6 +47,7 @@
|
||||
* given directive.
|
||||
*/
|
||||
#define WS "[[:space:]]+"
|
||||
#define ANY "(.+)"
|
||||
#define STR "\"([^\"]+)\""
|
||||
#define BOOL "(yes|on|no|off)"
|
||||
#define INT "((0x)?[[:digit:]]+)"
|
||||
@ -160,6 +161,7 @@ static HANDLE_FUNC (handle_xtinyproxy);
|
||||
|
||||
#ifdef UPSTREAM_SUPPORT
|
||||
static HANDLE_FUNC (handle_upstream);
|
||||
static HANDLE_FUNC (handle_upstream_auth);
|
||||
static HANDLE_FUNC (handle_upstream_no);
|
||||
#endif
|
||||
|
||||
@ -257,6 +259,10 @@ struct {
|
||||
BEGIN "(upstream)" WS "(" IP "|" ALNUM ")" ":" INT "(" WS STR
|
||||
")?" END, handle_upstream, NULL
|
||||
},
|
||||
{
|
||||
BEGIN "(upstream)" WS ALNUM ":" ANY "@(" IP "|" ALNUM ")" ":" INT "(" WS STR
|
||||
")?" END, handle_upstream_auth, NULL
|
||||
},
|
||||
#endif
|
||||
/* loglevel */
|
||||
STDCONF ("loglevel", "(critical|error|warning|notice|connect|info)",
|
||||
@ -1084,11 +1090,41 @@ static HANDLE_FUNC (handle_upstream)
|
||||
if (match[10].rm_so != -1) {
|
||||
domain = get_string_arg (line, &match[10]);
|
||||
if (domain) {
|
||||
upstream_add (ip, port, domain, &conf->upstream_list);
|
||||
upstream_add (NULL, NULL, ip, port, domain, &conf->upstream_list);
|
||||
safefree (domain);
|
||||
}
|
||||
} else {
|
||||
upstream_add (ip, port, NULL, &conf->upstream_list);
|
||||
upstream_add (NULL, NULL, ip, port, NULL, &conf->upstream_list);
|
||||
}
|
||||
|
||||
safefree (ip);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static HANDLE_FUNC (handle_upstream_auth)
|
||||
{
|
||||
char *user;
|
||||
char *pass;
|
||||
char *ip;
|
||||
int port;
|
||||
char *domain;
|
||||
|
||||
ip = get_string_arg (line, &match[4]);
|
||||
if (!ip)
|
||||
return -1;
|
||||
user = get_string_arg (line, &match[2]);
|
||||
pass = get_string_arg (line, &match[3]);
|
||||
port = (int) get_long_arg (line, &match[9]);
|
||||
|
||||
if (match[10].rm_so != -1) {
|
||||
domain = get_string_arg (line, &match[12]);
|
||||
if (domain) {
|
||||
upstream_add (user, pass, ip, port, domain, &conf->upstream_list);
|
||||
safefree (domain);
|
||||
}
|
||||
} else {
|
||||
upstream_add (user, pass, ip, port, NULL, &conf->upstream_list);
|
||||
}
|
||||
|
||||
safefree (ip);
|
||||
@ -1104,7 +1140,7 @@ static HANDLE_FUNC (handle_upstream_no)
|
||||
if (!domain)
|
||||
return -1;
|
||||
|
||||
upstream_add (NULL, 0, domain, &conf->upstream_list);
|
||||
upstream_add (NULL, NULL, NULL, 0, domain, &conf->upstream_list);
|
||||
safefree (domain);
|
||||
|
||||
return 0;
|
||||
|
51
src/reqs.c
51
src/reqs.c
@ -61,6 +61,41 @@
|
||||
#ifdef UPSTREAM_SUPPORT
|
||||
# define UPSTREAM_CONFIGURED() (config.upstream_list != NULL)
|
||||
# define UPSTREAM_HOST(host) upstream_get(host, config.upstream_list)
|
||||
static const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
static void encode_base_64(char* src, char* dest, int max_len) {
|
||||
int n, l, i;
|
||||
l = strlen(src);
|
||||
max_len = (max_len - 1) / 4;
|
||||
for (i = 0; i < max_len; i++, src += 3, l -= 3) {
|
||||
switch (l) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
n = src[0] << 16;
|
||||
*dest++ = base64[(n >> 18) & 077];
|
||||
*dest++ = base64[(n >> 12) & 077];
|
||||
*dest++ = '=';
|
||||
*dest++ = '=';
|
||||
break;
|
||||
case 2:
|
||||
n = src[0] << 16 | src[1] << 8;
|
||||
*dest++ = base64[(n >> 18) & 077];
|
||||
*dest++ = base64[(n >> 12) & 077];
|
||||
*dest++ = base64[(n >> 6) & 077];
|
||||
*dest++ = '=';
|
||||
break;
|
||||
default:
|
||||
n = src[0] << 16 | src[1] << 8 | src[2];
|
||||
*dest++ = base64[(n >> 18) & 077];
|
||||
*dest++ = base64[(n >> 12) & 077];
|
||||
*dest++ = base64[(n >> 6) & 077];
|
||||
*dest++ = base64[n & 077];
|
||||
}
|
||||
if (l < 3) break;
|
||||
}
|
||||
*dest++ = 0;
|
||||
}
|
||||
#else
|
||||
# define UPSTREAM_CONFIGURED() (0)
|
||||
# define UPSTREAM_HOST(host) (NULL)
|
||||
@ -1498,6 +1533,22 @@ void handle_connection (int fd)
|
||||
|
||||
connptr->upstream_proxy = UPSTREAM_HOST (request->host);
|
||||
if (connptr->upstream_proxy != NULL) {
|
||||
if (connptr->upstream_proxy->user)
|
||||
{
|
||||
char proxy_auth[200] = "";
|
||||
char src[256];
|
||||
char dst2[512];
|
||||
strcpy(src, connptr->upstream_proxy->user);
|
||||
strcat(src, ":");
|
||||
strcat(src, connptr->upstream_proxy->pass);
|
||||
encode_base_64(src, dst2, 512);
|
||||
strcat(proxy_auth, "Basic ");
|
||||
strcat(proxy_auth, dst2);
|
||||
|
||||
hashmap_insert (hashofheaders,
|
||||
"Proxy-Authorization",
|
||||
proxy_auth, strlen (proxy_auth) + 1);
|
||||
}
|
||||
if (connect_to_upstream (connptr, request) < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
@ -32,7 +32,7 @@
|
||||
/**
|
||||
* Construct an upstream struct from input data.
|
||||
*/
|
||||
static struct upstream *upstream_build (const char *host, int port, const char *domain)
|
||||
static struct upstream *upstream_build (const char *user, const char *pass, const char *host, int port, const char *domain)
|
||||
{
|
||||
char *ptr;
|
||||
struct upstream *up;
|
||||
@ -44,9 +44,18 @@ static struct upstream *upstream_build (const char *host, int port, const char *
|
||||
return NULL;
|
||||
}
|
||||
|
||||
up->host = up->domain = NULL;
|
||||
up->user = up->pass = up->host = up->domain = NULL;
|
||||
up->ip = up->mask = 0;
|
||||
|
||||
if (user != NULL) {
|
||||
up->user = safestrdup(user);
|
||||
}
|
||||
|
||||
if (pass != NULL) {
|
||||
up->pass = safestrdup(pass);
|
||||
}
|
||||
|
||||
|
||||
if (domain == NULL) {
|
||||
if (!host || host[0] == '\0' || port < 1) {
|
||||
log_message (LOG_WARNING,
|
||||
@ -57,8 +66,8 @@ static struct upstream *upstream_build (const char *host, int port, const char *
|
||||
up->host = safestrdup (host);
|
||||
up->port = port;
|
||||
|
||||
log_message (LOG_INFO, "Added upstream %s:%d for [default]",
|
||||
host, port);
|
||||
log_message (LOG_INFO, "Added upstream %s:<hidden>@%s:%d for [default]",
|
||||
user, host, port);
|
||||
} else if (host == NULL) {
|
||||
if (!domain || domain[0] == '\0') {
|
||||
log_message (LOG_WARNING,
|
||||
@ -101,13 +110,15 @@ static struct upstream *upstream_build (const char *host, int port, const char *
|
||||
up->port = port;
|
||||
up->domain = safestrdup (domain);
|
||||
|
||||
log_message (LOG_INFO, "Added upstream %s:%d for %s",
|
||||
host, port, domain);
|
||||
log_message (LOG_INFO, "Added upstream %s:<hidden>@%s:%d for %s",
|
||||
user, host, port, domain);
|
||||
}
|
||||
|
||||
return up;
|
||||
|
||||
fail:
|
||||
safefree (up->user);
|
||||
safefree (up->pass);
|
||||
safefree (up->host);
|
||||
safefree (up->domain);
|
||||
safefree (up);
|
||||
@ -118,12 +129,12 @@ fail:
|
||||
/*
|
||||
* Add an entry to the upstream list
|
||||
*/
|
||||
void upstream_add (const char *host, int port, const char *domain,
|
||||
void upstream_add (const char *user, const char *pass, const char *host, int port, const char *domain,
|
||||
struct upstream **upstream_list)
|
||||
{
|
||||
struct upstream *up;
|
||||
|
||||
up = upstream_build (host, port, domain);
|
||||
up = upstream_build (user, pass, host, port, domain);
|
||||
if (up == NULL) {
|
||||
return;
|
||||
}
|
||||
@ -154,6 +165,8 @@ void upstream_add (const char *host, int port, const char *domain,
|
||||
return;
|
||||
|
||||
upstream_cleanup:
|
||||
safefree (up->user);
|
||||
safefree (up->pass);
|
||||
safefree (up->host);
|
||||
safefree (up->domain);
|
||||
safefree (up);
|
||||
@ -215,6 +228,8 @@ void free_upstream_list (struct upstream *up)
|
||||
while (up) {
|
||||
struct upstream *tmp = up;
|
||||
up = up->next;
|
||||
safefree (tmp->user);
|
||||
safefree (tmp->pass);
|
||||
safefree (tmp->domain);
|
||||
safefree (tmp->host);
|
||||
safefree (tmp);
|
||||
|
@ -35,12 +35,14 @@ struct upstream {
|
||||
struct upstream *next;
|
||||
char *domain; /* optional */
|
||||
char *host;
|
||||
char *user;
|
||||
char *pass;
|
||||
int port;
|
||||
in_addr_t ip, mask;
|
||||
};
|
||||
|
||||
#ifdef UPSTREAM_SUPPORT
|
||||
extern void upstream_add (const char *host, int port, const char *domain,
|
||||
extern void upstream_add (const char *user, const char *pass, const char *host, int port, const char *domain,
|
||||
struct upstream **upstream_list);
|
||||
extern struct upstream *upstream_get (char *host, struct upstream *up);
|
||||
extern void free_upstream_list (struct upstream *up);
|
||||
|
Loading…
Reference in New Issue
Block a user