implement HTTP basic auth for upstream proxies
loosely based on @valenbg1's code from PR #38 closes #38 closes #96
This commit is contained in:
parent
4d9891e59e
commit
bf76aeeba1
@ -146,6 +146,9 @@ LogLevel Info
|
||||
# upstream testproxy:8008 ".our_testbed.example.com"
|
||||
# upstream testproxy:8008 "192.168.128.0/255.255.254.0"
|
||||
#
|
||||
# # upstream proxy using basic authentication
|
||||
# upstream user:pass@testproxy:8008 ".test.domain.invalid"
|
||||
#
|
||||
# # no upstream proxy for internal websites and unqualified hosts
|
||||
# no upstream ".internal.example.com"
|
||||
# no upstream "www.example.com"
|
||||
|
44
src/conf.c
44
src/conf.c
@ -259,8 +259,11 @@ struct {
|
||||
BEGIN "(no" WS "upstream)" WS STR END, handle_upstream_no, NULL
|
||||
},
|
||||
{
|
||||
BEGIN "(upstream)" WS "(" IP "|" ALNUM ")" ":" INT "(" WS STR
|
||||
")?" END, handle_upstream, NULL
|
||||
BEGIN "(upstream)" WS
|
||||
"(" ALNUM /*username*/ ":" ALNUM /*password*/ "@" ")?"
|
||||
"(" IP "|" ALNUM ")"
|
||||
":" INT "(" WS STR ")?"
|
||||
END, handle_upstream, NULL
|
||||
},
|
||||
{
|
||||
BEGIN "(upstream4)" WS "(" IP "|" ALNUM ")" ":" INT "(" WS STR
|
||||
@ -1100,24 +1103,33 @@ static int _handle_upstream(struct config_s* conf, const char* line,
|
||||
regmatch_t match[], proxy_type type)
|
||||
{
|
||||
char *ip;
|
||||
int port;
|
||||
char *domain;
|
||||
int port, mi = 3;
|
||||
char *domain = 0, *user = 0, *pass = 0;
|
||||
|
||||
ip = get_string_arg (line, &match[2]);
|
||||
if (match[mi].rm_so != -1)
|
||||
user = get_string_arg (line, &match[mi]);
|
||||
mi++;
|
||||
|
||||
if (match[mi].rm_so != -1)
|
||||
pass = get_string_arg (line, &match[mi]);
|
||||
mi++;
|
||||
|
||||
ip = get_string_arg (line, &match[mi]);
|
||||
if (!ip)
|
||||
return -1;
|
||||
port = (int) get_long_arg (line, &match[7]);
|
||||
mi += 5;
|
||||
|
||||
if (match[10].rm_so != -1) {
|
||||
domain = get_string_arg (line, &match[10]);
|
||||
if (domain) {
|
||||
upstream_add (ip, port, domain, type, &conf->upstream_list);
|
||||
safefree (domain);
|
||||
}
|
||||
} else {
|
||||
upstream_add (ip, port, NULL, type, &conf->upstream_list);
|
||||
}
|
||||
port = (int) get_long_arg (line, &match[mi]);
|
||||
mi += 3;
|
||||
|
||||
if (match[mi].rm_so != -1)
|
||||
domain = get_string_arg (line, &match[mi]);
|
||||
|
||||
upstream_add (ip, port, domain, user, pass, type, &conf->upstream_list);
|
||||
|
||||
safefree (user);
|
||||
safefree (pass);
|
||||
safefree (domain);
|
||||
safefree (ip);
|
||||
|
||||
return 0;
|
||||
@ -1146,7 +1158,7 @@ static HANDLE_FUNC (handle_upstream_no)
|
||||
if (!domain)
|
||||
return -1;
|
||||
|
||||
upstream_add (NULL, 0, domain, HTTP_TYPE, &conf->upstream_list);
|
||||
upstream_add (NULL, 0, domain, 0, 0, HTTP_TYPE, &conf->upstream_list);
|
||||
safefree (domain);
|
||||
|
||||
return 0;
|
||||
|
11
src/reqs.c
11
src/reqs.c
@ -270,6 +270,17 @@ establish_http_connection (struct conn_s *connptr, struct request_s *request)
|
||||
"Connection: close\r\n",
|
||||
request->method, request->path,
|
||||
request->host, portbuff);
|
||||
} else if (connptr->upstream_proxy &&
|
||||
connptr->upstream_proxy->type == HTTP_TYPE &&
|
||||
connptr->upstream_proxy->ua.authstr) {
|
||||
return write_message (connptr->server_fd,
|
||||
"%s %s HTTP/1.0\r\n"
|
||||
"Host: %s%s\r\n"
|
||||
"Connection: close\r\n"
|
||||
"Proxy-Authorization: Basic %s\r\n",
|
||||
request->method, request->path,
|
||||
request->host, portbuff,
|
||||
connptr->upstream_proxy->ua.authstr);
|
||||
} else {
|
||||
return write_message (connptr->server_fd,
|
||||
"%s %s HTTP/1.0\r\n"
|
||||
|
@ -27,6 +27,8 @@
|
||||
#include "upstream.h"
|
||||
#include "heap.h"
|
||||
#include "log.h"
|
||||
#include "base64.h"
|
||||
#include "basicauth.h"
|
||||
|
||||
#ifdef UPSTREAM_SUPPORT
|
||||
const char *
|
||||
@ -44,6 +46,7 @@ proxy_type_name(proxy_type type)
|
||||
* Construct an upstream struct from input data.
|
||||
*/
|
||||
static struct upstream *upstream_build (const char *host, int port, const char *domain,
|
||||
const char *user, const char *pass,
|
||||
proxy_type type)
|
||||
{
|
||||
char *ptr;
|
||||
@ -57,8 +60,24 @@ static struct upstream *upstream_build (const char *host, int port, const char *
|
||||
}
|
||||
|
||||
up->type = type;
|
||||
up->host = up->domain = NULL;
|
||||
up->host = up->domain = up->ua.user = up->pass = NULL;
|
||||
up->ip = up->mask = 0;
|
||||
if (user) {
|
||||
if (type == HTTP_TYPE) {
|
||||
char b[BASE64ENC_BYTES((256+2)-1) + 1];
|
||||
ssize_t ret;
|
||||
ret = basicauth_string(user, pass, b, sizeof b);
|
||||
if (ret == 0) {
|
||||
log_message (LOG_ERR,
|
||||
"User / pass in upstream config too long");
|
||||
return NULL;
|
||||
}
|
||||
up->ua.authstr = safestrdup (b);
|
||||
} else {
|
||||
up->ua.user = safestrdup (user);
|
||||
up->pass = safestrdup (pass);
|
||||
}
|
||||
}
|
||||
|
||||
if (domain == NULL) {
|
||||
if (!host || host[0] == '\0' || port < 1) {
|
||||
@ -121,6 +140,8 @@ static struct upstream *upstream_build (const char *host, int port, const char *
|
||||
return up;
|
||||
|
||||
fail:
|
||||
safefree (up->ua.user);
|
||||
safefree (up->pass);
|
||||
safefree (up->host);
|
||||
safefree (up->domain);
|
||||
safefree (up);
|
||||
@ -132,11 +153,12 @@ fail:
|
||||
* Add an entry to the upstream list
|
||||
*/
|
||||
void upstream_add (const char *host, int port, const char *domain,
|
||||
const char *user, const char *pass,
|
||||
proxy_type type, struct upstream **upstream_list)
|
||||
{
|
||||
struct upstream *up;
|
||||
|
||||
up = upstream_build (host, port, domain, type);
|
||||
up = upstream_build (host, port, domain, user, pass, type);
|
||||
if (up == NULL) {
|
||||
return;
|
||||
}
|
||||
|
@ -36,6 +36,11 @@ struct upstream {
|
||||
struct upstream *next;
|
||||
char *domain; /* optional */
|
||||
char *host;
|
||||
union {
|
||||
char *user;
|
||||
char *authstr;
|
||||
} ua;
|
||||
char *pass;
|
||||
int port;
|
||||
in_addr_t ip, mask;
|
||||
proxy_type type;
|
||||
@ -44,6 +49,7 @@ struct upstream {
|
||||
#ifdef UPSTREAM_SUPPORT
|
||||
const char *proxy_type_name(proxy_type type);
|
||||
extern void upstream_add (const char *host, int port, const char *domain,
|
||||
const char *user, const char *pass,
|
||||
proxy_type type, struct upstream **upstream_list);
|
||||
extern struct upstream *upstream_get (char *host, struct upstream *up);
|
||||
extern void free_upstream_list (struct upstream *up);
|
||||
|
Loading…
x
Reference in New Issue
Block a user