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
|
# # default upstream is internet firewall
|
||||||
# upstream firewall.internal.example.com:80
|
# 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
|
# The LAST matching rule wins the route decision. As you can see, you
|
||||||
# can use a host, or a domain:
|
# can use a host, or a domain:
|
||||||
# name matches host exactly
|
# name matches host exactly
|
||||||
|
42
src/conf.c
42
src/conf.c
@ -47,6 +47,7 @@
|
|||||||
* given directive.
|
* given directive.
|
||||||
*/
|
*/
|
||||||
#define WS "[[:space:]]+"
|
#define WS "[[:space:]]+"
|
||||||
|
#define ANY "(.+)"
|
||||||
#define STR "\"([^\"]+)\""
|
#define STR "\"([^\"]+)\""
|
||||||
#define BOOL "(yes|on|no|off)"
|
#define BOOL "(yes|on|no|off)"
|
||||||
#define INT "((0x)?[[:digit:]]+)"
|
#define INT "((0x)?[[:digit:]]+)"
|
||||||
@ -160,6 +161,7 @@ static HANDLE_FUNC (handle_xtinyproxy);
|
|||||||
|
|
||||||
#ifdef UPSTREAM_SUPPORT
|
#ifdef UPSTREAM_SUPPORT
|
||||||
static HANDLE_FUNC (handle_upstream);
|
static HANDLE_FUNC (handle_upstream);
|
||||||
|
static HANDLE_FUNC (handle_upstream_auth);
|
||||||
static HANDLE_FUNC (handle_upstream_no);
|
static HANDLE_FUNC (handle_upstream_no);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -257,6 +259,10 @@ struct {
|
|||||||
BEGIN "(upstream)" WS "(" IP "|" ALNUM ")" ":" INT "(" WS STR
|
BEGIN "(upstream)" WS "(" IP "|" ALNUM ")" ":" INT "(" WS STR
|
||||||
")?" END, handle_upstream, NULL
|
")?" END, handle_upstream, NULL
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
BEGIN "(upstream)" WS ALNUM ":" ANY "@(" IP "|" ALNUM ")" ":" INT "(" WS STR
|
||||||
|
")?" END, handle_upstream_auth, NULL
|
||||||
|
},
|
||||||
#endif
|
#endif
|
||||||
/* loglevel */
|
/* loglevel */
|
||||||
STDCONF ("loglevel", "(critical|error|warning|notice|connect|info)",
|
STDCONF ("loglevel", "(critical|error|warning|notice|connect|info)",
|
||||||
@ -1084,11 +1090,41 @@ static HANDLE_FUNC (handle_upstream)
|
|||||||
if (match[10].rm_so != -1) {
|
if (match[10].rm_so != -1) {
|
||||||
domain = get_string_arg (line, &match[10]);
|
domain = get_string_arg (line, &match[10]);
|
||||||
if (domain) {
|
if (domain) {
|
||||||
upstream_add (ip, port, domain, &conf->upstream_list);
|
upstream_add (NULL, NULL, ip, port, domain, &conf->upstream_list);
|
||||||
safefree (domain);
|
safefree (domain);
|
||||||
}
|
}
|
||||||
} else {
|
} 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);
|
safefree (ip);
|
||||||
@ -1104,7 +1140,7 @@ static HANDLE_FUNC (handle_upstream_no)
|
|||||||
if (!domain)
|
if (!domain)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
upstream_add (NULL, 0, domain, &conf->upstream_list);
|
upstream_add (NULL, NULL, NULL, 0, domain, &conf->upstream_list);
|
||||||
safefree (domain);
|
safefree (domain);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
51
src/reqs.c
51
src/reqs.c
@ -61,6 +61,41 @@
|
|||||||
#ifdef UPSTREAM_SUPPORT
|
#ifdef UPSTREAM_SUPPORT
|
||||||
# define UPSTREAM_CONFIGURED() (config.upstream_list != NULL)
|
# define UPSTREAM_CONFIGURED() (config.upstream_list != NULL)
|
||||||
# define UPSTREAM_HOST(host) upstream_get(host, config.upstream_list)
|
# 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
|
#else
|
||||||
# define UPSTREAM_CONFIGURED() (0)
|
# define UPSTREAM_CONFIGURED() (0)
|
||||||
# define UPSTREAM_HOST(host) (NULL)
|
# define UPSTREAM_HOST(host) (NULL)
|
||||||
@ -1498,6 +1533,22 @@ void handle_connection (int fd)
|
|||||||
|
|
||||||
connptr->upstream_proxy = UPSTREAM_HOST (request->host);
|
connptr->upstream_proxy = UPSTREAM_HOST (request->host);
|
||||||
if (connptr->upstream_proxy != NULL) {
|
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) {
|
if (connect_to_upstream (connptr, request) < 0) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
/**
|
/**
|
||||||
* Construct an upstream struct from input data.
|
* 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;
|
char *ptr;
|
||||||
struct upstream *up;
|
struct upstream *up;
|
||||||
@ -44,9 +44,18 @@ static struct upstream *upstream_build (const char *host, int port, const char *
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
up->host = up->domain = NULL;
|
up->user = up->pass = up->host = up->domain = NULL;
|
||||||
up->ip = up->mask = 0;
|
up->ip = up->mask = 0;
|
||||||
|
|
||||||
|
if (user != NULL) {
|
||||||
|
up->user = safestrdup(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pass != NULL) {
|
||||||
|
up->pass = safestrdup(pass);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (domain == NULL) {
|
if (domain == NULL) {
|
||||||
if (!host || host[0] == '\0' || port < 1) {
|
if (!host || host[0] == '\0' || port < 1) {
|
||||||
log_message (LOG_WARNING,
|
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->host = safestrdup (host);
|
||||||
up->port = port;
|
up->port = port;
|
||||||
|
|
||||||
log_message (LOG_INFO, "Added upstream %s:%d for [default]",
|
log_message (LOG_INFO, "Added upstream %s:<hidden>@%s:%d for [default]",
|
||||||
host, port);
|
user, host, port);
|
||||||
} else if (host == NULL) {
|
} else if (host == NULL) {
|
||||||
if (!domain || domain[0] == '\0') {
|
if (!domain || domain[0] == '\0') {
|
||||||
log_message (LOG_WARNING,
|
log_message (LOG_WARNING,
|
||||||
@ -101,13 +110,15 @@ static struct upstream *upstream_build (const char *host, int port, const char *
|
|||||||
up->port = port;
|
up->port = port;
|
||||||
up->domain = safestrdup (domain);
|
up->domain = safestrdup (domain);
|
||||||
|
|
||||||
log_message (LOG_INFO, "Added upstream %s:%d for %s",
|
log_message (LOG_INFO, "Added upstream %s:<hidden>@%s:%d for %s",
|
||||||
host, port, domain);
|
user, host, port, domain);
|
||||||
}
|
}
|
||||||
|
|
||||||
return up;
|
return up;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
safefree (up->user);
|
||||||
|
safefree (up->pass);
|
||||||
safefree (up->host);
|
safefree (up->host);
|
||||||
safefree (up->domain);
|
safefree (up->domain);
|
||||||
safefree (up);
|
safefree (up);
|
||||||
@ -118,12 +129,12 @@ fail:
|
|||||||
/*
|
/*
|
||||||
* Add an entry to the upstream list
|
* 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 **upstream_list)
|
||||||
{
|
{
|
||||||
struct upstream *up;
|
struct upstream *up;
|
||||||
|
|
||||||
up = upstream_build (host, port, domain);
|
up = upstream_build (user, pass, host, port, domain);
|
||||||
if (up == NULL) {
|
if (up == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -154,6 +165,8 @@ void upstream_add (const char *host, int port, const char *domain,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
upstream_cleanup:
|
upstream_cleanup:
|
||||||
|
safefree (up->user);
|
||||||
|
safefree (up->pass);
|
||||||
safefree (up->host);
|
safefree (up->host);
|
||||||
safefree (up->domain);
|
safefree (up->domain);
|
||||||
safefree (up);
|
safefree (up);
|
||||||
@ -215,6 +228,8 @@ void free_upstream_list (struct upstream *up)
|
|||||||
while (up) {
|
while (up) {
|
||||||
struct upstream *tmp = up;
|
struct upstream *tmp = up;
|
||||||
up = up->next;
|
up = up->next;
|
||||||
|
safefree (tmp->user);
|
||||||
|
safefree (tmp->pass);
|
||||||
safefree (tmp->domain);
|
safefree (tmp->domain);
|
||||||
safefree (tmp->host);
|
safefree (tmp->host);
|
||||||
safefree (tmp);
|
safefree (tmp);
|
||||||
|
@ -35,12 +35,14 @@ struct upstream {
|
|||||||
struct upstream *next;
|
struct upstream *next;
|
||||||
char *domain; /* optional */
|
char *domain; /* optional */
|
||||||
char *host;
|
char *host;
|
||||||
|
char *user;
|
||||||
|
char *pass;
|
||||||
int port;
|
int port;
|
||||||
in_addr_t ip, mask;
|
in_addr_t ip, mask;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef UPSTREAM_SUPPORT
|
#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);
|
struct upstream **upstream_list);
|
||||||
extern struct upstream *upstream_get (char *host, struct upstream *up);
|
extern struct upstream *upstream_get (char *host, struct upstream *up);
|
||||||
extern void free_upstream_list (struct upstream *up);
|
extern void free_upstream_list (struct upstream *up);
|
||||||
|
Loading…
Reference in New Issue
Block a user