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 ".our_testbed.example.com"
|
||||||
# upstream testproxy:8008 "192.168.128.0/255.255.254.0"
|
# 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 proxy for internal websites and unqualified hosts
|
||||||
# no upstream ".internal.example.com"
|
# no upstream ".internal.example.com"
|
||||||
# no upstream "www.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 "(no" WS "upstream)" WS STR END, handle_upstream_no, NULL
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
BEGIN "(upstream)" WS "(" IP "|" ALNUM ")" ":" INT "(" WS STR
|
BEGIN "(upstream)" WS
|
||||||
")?" END, handle_upstream, NULL
|
"(" ALNUM /*username*/ ":" ALNUM /*password*/ "@" ")?"
|
||||||
|
"(" IP "|" ALNUM ")"
|
||||||
|
":" INT "(" WS STR ")?"
|
||||||
|
END, handle_upstream, NULL
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
BEGIN "(upstream4)" WS "(" IP "|" ALNUM ")" ":" INT "(" WS STR
|
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)
|
regmatch_t match[], proxy_type type)
|
||||||
{
|
{
|
||||||
char *ip;
|
char *ip;
|
||||||
int port;
|
int port, mi = 3;
|
||||||
char *domain;
|
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)
|
if (!ip)
|
||||||
return -1;
|
return -1;
|
||||||
port = (int) get_long_arg (line, &match[7]);
|
mi += 5;
|
||||||
|
|
||||||
if (match[10].rm_so != -1) {
|
port = (int) get_long_arg (line, &match[mi]);
|
||||||
domain = get_string_arg (line, &match[10]);
|
mi += 3;
|
||||||
if (domain) {
|
|
||||||
upstream_add (ip, port, domain, type, &conf->upstream_list);
|
|
||||||
safefree (domain);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
upstream_add (ip, port, NULL, type, &conf->upstream_list);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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);
|
safefree (ip);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -1146,7 +1158,7 @@ static HANDLE_FUNC (handle_upstream_no)
|
|||||||
if (!domain)
|
if (!domain)
|
||||||
return -1;
|
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);
|
safefree (domain);
|
||||||
|
|
||||||
return 0;
|
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",
|
"Connection: close\r\n",
|
||||||
request->method, request->path,
|
request->method, request->path,
|
||||||
request->host, portbuff);
|
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 {
|
} else {
|
||||||
return write_message (connptr->server_fd,
|
return write_message (connptr->server_fd,
|
||||||
"%s %s HTTP/1.0\r\n"
|
"%s %s HTTP/1.0\r\n"
|
||||||
|
@ -27,6 +27,8 @@
|
|||||||
#include "upstream.h"
|
#include "upstream.h"
|
||||||
#include "heap.h"
|
#include "heap.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "base64.h"
|
||||||
|
#include "basicauth.h"
|
||||||
|
|
||||||
#ifdef UPSTREAM_SUPPORT
|
#ifdef UPSTREAM_SUPPORT
|
||||||
const char *
|
const char *
|
||||||
@ -44,6 +46,7 @@ proxy_type_name(proxy_type type)
|
|||||||
* 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 *host, int port, const char *domain,
|
||||||
|
const char *user, const char *pass,
|
||||||
proxy_type type)
|
proxy_type type)
|
||||||
{
|
{
|
||||||
char *ptr;
|
char *ptr;
|
||||||
@ -57,8 +60,24 @@ static struct upstream *upstream_build (const char *host, int port, const char *
|
|||||||
}
|
}
|
||||||
|
|
||||||
up->type = type;
|
up->type = type;
|
||||||
up->host = up->domain = NULL;
|
up->host = up->domain = up->ua.user = up->pass = NULL;
|
||||||
up->ip = up->mask = 0;
|
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 (domain == NULL) {
|
||||||
if (!host || host[0] == '\0' || port < 1) {
|
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;
|
return up;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
safefree (up->ua.user);
|
||||||
|
safefree (up->pass);
|
||||||
safefree (up->host);
|
safefree (up->host);
|
||||||
safefree (up->domain);
|
safefree (up->domain);
|
||||||
safefree (up);
|
safefree (up);
|
||||||
@ -132,11 +153,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 *host, int port, const char *domain,
|
||||||
|
const char *user, const char *pass,
|
||||||
proxy_type type, struct upstream **upstream_list)
|
proxy_type type, struct upstream **upstream_list)
|
||||||
{
|
{
|
||||||
struct upstream *up;
|
struct upstream *up;
|
||||||
|
|
||||||
up = upstream_build (host, port, domain, type);
|
up = upstream_build (host, port, domain, user, pass, type);
|
||||||
if (up == NULL) {
|
if (up == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,11 @@ struct upstream {
|
|||||||
struct upstream *next;
|
struct upstream *next;
|
||||||
char *domain; /* optional */
|
char *domain; /* optional */
|
||||||
char *host;
|
char *host;
|
||||||
|
union {
|
||||||
|
char *user;
|
||||||
|
char *authstr;
|
||||||
|
} ua;
|
||||||
|
char *pass;
|
||||||
int port;
|
int port;
|
||||||
in_addr_t ip, mask;
|
in_addr_t ip, mask;
|
||||||
proxy_type type;
|
proxy_type type;
|
||||||
@ -44,6 +49,7 @@ struct upstream {
|
|||||||
#ifdef UPSTREAM_SUPPORT
|
#ifdef UPSTREAM_SUPPORT
|
||||||
const char *proxy_type_name(proxy_type type);
|
const char *proxy_type_name(proxy_type type);
|
||||||
extern void upstream_add (const char *host, int port, const char *domain,
|
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);
|
proxy_type type, 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