Add WITHOUT_USERAUTH switch

pull/48/head
Soner Tari 4 years ago
parent ca79405769
commit 6f5a7ceeb1

@ -75,6 +75,13 @@
#FEATURES+= -DWITH_SSLV2 #FEATURES+= -DWITH_SSLV2
### User Authentication
# Define to disable support for user authentication.
# Doing so will remove the dependency on sqlite.
#FEATURES+= -DWITHOUT_USERAUTH
### Debugging ### Debugging
# These flags are added to CFLAGS iff building from a git repo. # These flags are added to CFLAGS iff building from a git repo.
@ -281,10 +288,12 @@ PKGS+= $(shell $(PKGCONFIG) $(PCFLAGS) --exists libpcap \
&& echo libpcap) && echo libpcap)
endif endif
endif endif
ifneq ($(filter -DWITHOUT_USERAUTH,$(FEATURES)),-DWITHOUT_USERAUTH)
ifndef SQLITE_BASE ifndef SQLITE_BASE
PKGS+= $(shell $(PKGCONFIG) $(PCFLAGS) --exists sqlite3 \ PKGS+= $(shell $(PKGCONFIG) $(PCFLAGS) --exists sqlite3 \
&& echo sqlite3) && echo sqlite3)
endif endif
endif
TPKGS:= TPKGS:=
ifndef CHECK_BASE ifndef CHECK_BASE
TPKGS+= $(shell $(PKGCONFIG) $(PCFLAGS) --exists check \ TPKGS+= $(shell $(PKGCONFIG) $(PCFLAGS) --exists check \
@ -328,6 +337,7 @@ $(error dependency 'libpcap' not found; \
endif endif
endif endif
endif endif
ifneq ($(filter -DWITHOUT_USERAUTH,$(FEATURES)),-DWITHOUT_USERAUTH)
ifeq (,$(filter sqlite3,$(PKGS))) ifeq (,$(filter sqlite3,$(PKGS)))
SQLITE_FOUND:=$(call locate,sqlite3,include/sqlite3.h,$(SQLITE_BASE)) SQLITE_FOUND:=$(call locate,sqlite3,include/sqlite3.h,$(SQLITE_BASE))
ifndef SQLITE_FOUND ifndef SQLITE_FOUND
@ -335,6 +345,7 @@ $(error dependency 'SQLite3' not found; \
install it or point SQLITE_BASE to base path) install it or point SQLITE_BASE to base path)
endif endif
endif endif
endif
ifeq (,$(filter check,$(TPKGS))) ifeq (,$(filter check,$(TPKGS)))
CHECK_FOUND:= $(call locate,check,include/check.h,$(CHECK_BASE)) CHECK_FOUND:= $(call locate,check,include/check.h,$(CHECK_BASE))
ifndef CHECK_FOUND ifndef CHECK_FOUND
@ -385,11 +396,13 @@ PKG_LDFLAGS+= -L$(LIBPCAP_FOUND)/lib
PKG_LIBS+= -lpcap PKG_LIBS+= -lpcap
endif endif
endif endif
ifneq ($(filter -DWITHOUT_USERAUTH,$(FEATURES)),-DWITHOUT_USERAUTH)
ifdef SQLITE_FOUND ifdef SQLITE_FOUND
PKG_CPPFLAGS+= -I$(SQLITE_FOUND)/include PKG_CPPFLAGS+= -I$(SQLITE_FOUND)/include
PKG_LDFLAGS+= -L$(SQLITE_FOUND)/lib PKG_LDFLAGS+= -L$(SQLITE_FOUND)/lib
PKG_LIBS+= -lsqlite3 PKG_LIBS+= -lsqlite3
endif endif
endif
ifdef CHECK_FOUND ifdef CHECK_FOUND
TPKG_CPPFLAGS+= -I$(CHECK_FOUND)/include TPKG_CPPFLAGS+= -I$(CHECK_FOUND)/include
TPKG_LDFLAGS+= -L$(CHECK_FOUND)/lib TPKG_LDFLAGS+= -L$(CHECK_FOUND)/lib

@ -135,8 +135,10 @@ main_version(void)
lpv += 16; lpv += 16;
fprintf(stderr, "rtlinked against libpcap %s\n", lpv); fprintf(stderr, "rtlinked against libpcap %s\n", lpv);
#endif /* !WITHOUT_MIRROR */ #endif /* !WITHOUT_MIRROR */
#ifndef WITHOUT_USERAUTH
fprintf(stderr, "compiled against sqlite %s\n", SQLITE_VERSION); fprintf(stderr, "compiled against sqlite %s\n", SQLITE_VERSION);
fprintf(stderr, "rtlinked against sqlite %s\n", sqlite3_libversion()); fprintf(stderr, "rtlinked against sqlite %s\n", sqlite3_libversion());
#endif /* !WITHOUT_USERAUTH */
fprintf(stderr, "%d CPU cores detected\n", sys_get_cpu_cores()); fprintf(stderr, "%d CPU cores detected\n", sys_get_cpu_cores());
} }
@ -641,6 +643,7 @@ main(int argc, char *argv[])
} }
} }
#ifndef WITHOUT_USERAUTH
if (global->opts->user_auth || global_has_userauth_spec(global)) { if (global->opts->user_auth || global_has_userauth_spec(global)) {
if (!global->userdb_path) { if (!global->userdb_path) {
fprintf(stderr, "User auth requires a userdb path\n"); fprintf(stderr, "User auth requires a userdb path\n");
@ -660,6 +663,7 @@ main(int argc, char *argv[])
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} }
#endif /* !WITHOUT_USERAUTH */
/* dynamic defaults */ /* dynamic defaults */
if (!global->opts->ciphers) { if (!global->opts->ciphers) {

@ -120,7 +120,9 @@ opts_new(void)
#endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */ #endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */
opts->remove_http_referer = 1; opts->remove_http_referer = 1;
opts->verify_peer = 1; opts->verify_peer = 1;
#ifndef WITHOUT_USERAUTH
opts->user_timeout = 300; opts->user_timeout = 300;
#endif /* !WITHOUT_USERAUTH */
opts->max_http_header_size = 8192; opts->max_http_header_size = 8192;
return opts; return opts;
} }
@ -177,19 +179,23 @@ opts_free(opts_t *opts)
if (opts->ciphersuites) { if (opts->ciphersuites) {
free(opts->ciphersuites); free(opts->ciphersuites);
} }
#ifndef WITHOUT_USERAUTH
if (opts->user_auth_url) { if (opts->user_auth_url) {
free(opts->user_auth_url); free(opts->user_auth_url);
} }
#endif /* !WITHOUT_USERAUTH */
passsite_t *passsite = opts->passsites; passsite_t *passsite = opts->passsites;
while (passsite) { while (passsite) {
passsite_t *next = passsite->next; passsite_t *next = passsite->next;
free(passsite->site); free(passsite->site);
if (passsite->ip) if (passsite->ip)
free(passsite->ip); free(passsite->ip);
#ifndef WITHOUT_USERAUTH
if (passsite->user) if (passsite->user)
free(passsite->user); free(passsite->user);
if (passsite->keyword) if (passsite->keyword)
free(passsite->keyword); free(passsite->keyword);
#endif /* !WITHOUT_USERAUTH */
free(passsite); free(passsite);
passsite = next; passsite = next;
} }
@ -327,6 +333,7 @@ global_free(global_t *global)
free(global->mirrortarget); free(global->mirrortarget);
} }
#endif /* !WITHOUT_MIRROR */ #endif /* !WITHOUT_MIRROR */
#ifndef WITHOUT_USERAUTH
if (global->userdb_path) { if (global->userdb_path) {
free(global->userdb_path); free(global->userdb_path);
} }
@ -335,6 +342,7 @@ global_free(global_t *global)
sqlite3_finalize(global->update_user_atime); sqlite3_finalize(global->update_user_atime);
sqlite3_close(global->userdb); sqlite3_close(global->userdb);
} }
#endif /* !WITHOUT_USERAUTH */
if (global->opts) { if (global->opts) {
opts_free(global->opts); opts_free(global->opts);
} }
@ -387,6 +395,7 @@ global_has_dns_spec(global_t *global)
return 0; return 0;
} }
#ifndef WITHOUT_USERAUTH
/* /*
* Return 1 if global_t contains a proxyspec with user_auth, 0 otherwise. * Return 1 if global_t contains a proxyspec with user_auth, 0 otherwise.
*/ */
@ -403,6 +412,7 @@ global_has_userauth_spec(global_t *global)
return 0; return 0;
} }
#endif /* !WITHOUT_USERAUTH */
/* /*
* Return 1 if global_t contains a proxyspec with cakey defined, 0 otherwise. * Return 1 if global_t contains a proxyspec with cakey defined, 0 otherwise.
@ -531,6 +541,7 @@ opts_proto_dbg_dump(opts_t *opts)
return s; return s;
} }
#ifndef WITHOUT_USERAUTH
static void static void
opts_set_user_auth_url(opts_t *opts, const char *optarg) opts_set_user_auth_url(opts_t *opts, const char *optarg)
{ {
@ -541,6 +552,7 @@ opts_set_user_auth_url(opts_t *opts, const char *optarg)
log_dbg_printf("UserAuthURL: %s\n", opts->user_auth_url); log_dbg_printf("UserAuthURL: %s\n", opts->user_auth_url);
#endif /* DEBUG_OPTS */ #endif /* DEBUG_OPTS */
} }
#endif /* !WITHOUT_USERAUTH */
static opts_t * static opts_t *
clone_global_opts(global_t *global, const char *argv0, global_opts_str_t *global_opts_str) clone_global_opts(global_t *global, const char *argv0, global_opts_str_t *global_opts_str)
@ -583,8 +595,10 @@ clone_global_opts(global_t *global, const char *argv0, global_opts_str_t *global
opts->remove_http_referer = global->opts->remove_http_referer; opts->remove_http_referer = global->opts->remove_http_referer;
opts->verify_peer = global->opts->verify_peer; opts->verify_peer = global->opts->verify_peer;
opts->allow_wrong_host = global->opts->allow_wrong_host; opts->allow_wrong_host = global->opts->allow_wrong_host;
#ifndef WITHOUT_USERAUTH
opts->user_auth = global->opts->user_auth; opts->user_auth = global->opts->user_auth;
opts->user_timeout = global->opts->user_timeout; opts->user_timeout = global->opts->user_timeout;
#endif /* !WITHOUT_USERAUTH */
opts->validate_proto = global->opts->validate_proto; opts->validate_proto = global->opts->validate_proto;
opts->max_http_header_size = global->opts->max_http_header_size; opts->max_http_header_size = global->opts->max_http_header_size;
@ -624,9 +638,11 @@ clone_global_opts(global_t *global, const char *argv0, global_opts_str_t *global
if (global->opts->ciphersuites) { if (global->opts->ciphersuites) {
opts_set_ciphersuites(opts, argv0, global->opts->ciphersuites); opts_set_ciphersuites(opts, argv0, global->opts->ciphersuites);
} }
#ifndef WITHOUT_USERAUTH
if (global->opts->user_auth_url) { if (global->opts->user_auth_url) {
opts_set_user_auth_url(opts, global->opts->user_auth_url); opts_set_user_auth_url(opts, global->opts->user_auth_url);
} }
#endif /* !WITHOUT_USERAUTH */
passsite_t *passsite = global->opts->passsites; passsite_t *passsite = global->opts->passsites;
while (passsite) { while (passsite) {
@ -637,11 +653,13 @@ clone_global_opts(global_t *global, const char *argv0, global_opts_str_t *global
ps->site = strdup(passsite->site); ps->site = strdup(passsite->site);
if (passsite->ip) if (passsite->ip)
ps->ip = strdup(passsite->ip); ps->ip = strdup(passsite->ip);
#ifndef WITHOUT_USERAUTH
if (passsite->user) if (passsite->user)
ps->user = strdup(passsite->user); ps->user = strdup(passsite->user);
if (passsite->keyword) if (passsite->keyword)
ps->keyword = strdup(passsite->keyword); ps->keyword = strdup(passsite->keyword);
ps->all = passsite->all; ps->all = passsite->all;
#endif /* !WITHOUT_USERAUTH */
ps->next = opts->passsites; ps->next = opts->passsites;
opts->passsites = ps; opts->passsites = ps;
@ -941,8 +959,15 @@ passsite_str(passsite_t *passsite)
int count = 0; int count = 0;
while (passsite) { while (passsite) {
char *p; char *p;
if (asprintf(&p, "site=%s,ip=%s,user=%s,keyword=%s,all=%d", if (asprintf(&p, "site=%s,ip=%s"
passsite->site, STRORNONE(passsite->ip), STRORNONE(passsite->user), STRORNONE(passsite->keyword), passsite->all) < 0) { #ifndef WITHOUT_USERAUTH
",user=%s,keyword=%s,all=%d"
#endif /* !WITHOUT_USERAUTH */
, passsite->site, STRORNONE(passsite->ip)
#ifndef WITHOUT_USERAUTH
, STRORNONE(passsite->user), STRORNONE(passsite->keyword), passsite->all
#endif /* !WITHOUT_USERAUTH */
) < 0) {
goto err; goto err;
} }
char *nps; char *nps;
@ -1009,7 +1034,11 @@ opts_str(opts_t *opts)
#ifndef OPENSSL_NO_ECDH #ifndef OPENSSL_NO_ECDH
"|%s" "|%s"
#endif /* !OPENSSL_NO_ECDH */ #endif /* !OPENSSL_NO_ECDH */
"|%s%s%s%s%s%s|%s|%d%s|%d\n%s%s%s", "|%s%s%s%s%s"
#ifndef WITHOUT_USERAUTH
"%s|%s|%d"
#endif /* !WITHOUT_USERAUTH */
"%s|%d\n%s%s%s",
(!opts->sslcomp ? "no sslcomp" : ""), (!opts->sslcomp ? "no sslcomp" : ""),
#ifdef HAVE_SSLV2 #ifdef HAVE_SSLV2
(opts->no_ssl2 ? "|no_ssl2" : ""), (opts->no_ssl2 ? "|no_ssl2" : ""),
@ -1041,9 +1070,11 @@ opts_str(opts_t *opts)
(opts->remove_http_referer ? "|remove_http_referer" : ""), (opts->remove_http_referer ? "|remove_http_referer" : ""),
(opts->verify_peer ? "|verify_peer" : ""), (opts->verify_peer ? "|verify_peer" : ""),
(opts->allow_wrong_host ? "|allow_wrong_host" : ""), (opts->allow_wrong_host ? "|allow_wrong_host" : ""),
#ifndef WITHOUT_USERAUTH
(opts->user_auth ? "|user_auth" : ""), (opts->user_auth ? "|user_auth" : ""),
(opts->user_auth_url ? opts->user_auth_url : "no user_auth_url"), (opts->user_auth_url ? opts->user_auth_url : "no user_auth_url"),
opts->user_timeout, opts->user_timeout,
#endif /* !WITHOUT_USERAUTH */
(opts->validate_proto ? "|validate_proto" : ""), (opts->validate_proto ? "|validate_proto" : ""),
opts->max_http_header_size, opts->max_http_header_size,
proto_dump, proto_dump,
@ -1700,6 +1731,7 @@ opts_unset_allow_wrong_host(opts_t *opts)
opts->allow_wrong_host = 0; opts->allow_wrong_host = 0;
} }
#ifndef WITHOUT_USERAUTH
static void static void
opts_set_user_auth(UNUSED opts_t *opts) opts_set_user_auth(UNUSED opts_t *opts)
{ {
@ -1714,6 +1746,7 @@ opts_unset_user_auth(opts_t *opts)
{ {
opts->user_auth = 0; opts->user_auth = 0;
} }
#endif /* !WITHOUT_USERAUTH */
static void static void
opts_set_validate_proto(opts_t *opts) opts_set_validate_proto(opts_t *opts)
@ -1763,6 +1796,7 @@ opts_set_pass_site(opts_t *opts, char *value, int line_num)
ps->site = strdup(s); ps->site = strdup(s);
if (argc > 1) { if (argc > 1) {
#ifndef WITHOUT_USERAUTH
if (!strcmp(argv[1], "*")) { if (!strcmp(argv[1], "*")) {
ps->all = 1; ps->all = 1;
} else if (sys_isuser(argv[1])) { } else if (sys_isuser(argv[1])) {
@ -1772,8 +1806,11 @@ opts_set_pass_site(opts_t *opts, char *value, int line_num)
} }
ps->user = strdup(argv[1]); ps->user = strdup(argv[1]);
} else { } else {
#endif /* !WITHOUT_USERAUTH */
ps->ip = strdup(argv[1]); ps->ip = strdup(argv[1]);
#ifndef WITHOUT_USERAUTH
} }
#endif /* !WITHOUT_USERAUTH */
} }
if (argc > 2) { if (argc > 2) {
@ -1781,13 +1818,19 @@ opts_set_pass_site(opts_t *opts, char *value, int line_num)
fprintf(stderr, "PassSite client ip cannot define keyword filter on line %d\n", line_num); fprintf(stderr, "PassSite client ip cannot define keyword filter on line %d\n", line_num);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
#ifndef WITHOUT_USERAUTH
ps->keyword = strdup(argv[2]); ps->keyword = strdup(argv[2]);
#endif /* !WITHOUT_USERAUTH */
} }
ps->next = opts->passsites; ps->next = opts->passsites;
opts->passsites = ps; opts->passsites = ps;
#ifdef DEBUG_OPTS #ifdef DEBUG_OPTS
#ifndef WITHOUT_USERAUTH
log_dbg_printf("PassSite: %s, %s, %s, %s\n", ps->site, STRORDASH(ps->ip), ps->all ? "*" : STRORDASH(ps->user), STRORDASH(ps->keyword)); log_dbg_printf("PassSite: %s, %s, %s, %s\n", ps->site, STRORDASH(ps->ip), ps->all ? "*" : STRORDASH(ps->user), STRORDASH(ps->keyword));
#else /* WITHOUT_USERAUTH */
log_dbg_printf("PassSite: %s, %s\n", ps->site, STRORDASH(ps->ip));
#endif /* WITHOUT_USERAUTH */
#endif /* DEBUG_OPTS */ #endif /* DEBUG_OPTS */
} }
@ -2284,6 +2327,7 @@ global_unset_statslog(global_t *global)
global->statslog = 0; global->statslog = 0;
} }
#ifndef WITHOUT_USERAUTH
static void static void
global_set_userdb_path(global_t *global, const char *optarg) global_set_userdb_path(global_t *global, const char *optarg)
{ {
@ -2294,6 +2338,7 @@ global_set_userdb_path(global_t *global, const char *optarg)
log_dbg_printf("UserDBPath: %s\n", global->userdb_path); log_dbg_printf("UserDBPath: %s\n", global->userdb_path);
#endif /* DEBUG_OPTS */ #endif /* DEBUG_OPTS */
} }
#endif /* !WITHOUT_USERAUTH */
int int
check_value_yesno(const char *value, const char *name, int line_num) check_value_yesno(const char *value, const char *name, int line_num)
@ -2393,6 +2438,7 @@ set_option(opts_t *opts, const char *argv0,
#ifdef DEBUG_OPTS #ifdef DEBUG_OPTS
log_dbg_printf("NATEngine: %s\n", *natengine); log_dbg_printf("NATEngine: %s\n", *natengine);
#endif /* DEBUG_OPTS */ #endif /* DEBUG_OPTS */
#ifndef WITHOUT_USERAUTH
} else if (equal(name, "UserAuth")) { } else if (equal(name, "UserAuth")) {
yes = check_value_yesno(value, "UserAuth", line_num); yes = check_value_yesno(value, "UserAuth", line_num);
if (yes == -1) { if (yes == -1) {
@ -2415,6 +2461,7 @@ set_option(opts_t *opts, const char *argv0,
#ifdef DEBUG_OPTS #ifdef DEBUG_OPTS
log_dbg_printf("UserTimeout: %u\n", opts->user_timeout); log_dbg_printf("UserTimeout: %u\n", opts->user_timeout);
#endif /* DEBUG_OPTS */ #endif /* DEBUG_OPTS */
#endif /* !WITHOUT_USERAUTH */
} else if (equal(name, "ValidateProto")) { } else if (equal(name, "ValidateProto")) {
yes = check_value_yesno(value, "ValidateProto", line_num); yes = check_value_yesno(value, "ValidateProto", line_num);
if (yes == -1) { if (yes == -1) {
@ -2816,8 +2863,10 @@ set_global_option(global_t *global, const char *argv0,
#endif /* DEBUG_OPTS */ #endif /* DEBUG_OPTS */
} else if (equal(name, "DebugLevel")) { } else if (equal(name, "DebugLevel")) {
global_set_debug_level(value); global_set_debug_level(value);
#ifndef WITHOUT_USERAUTH
} else if (equal(name, "UserDBPath")) { } else if (equal(name, "UserDBPath")) {
global_set_userdb_path(global, value); global_set_userdb_path(global, value);
#endif /* !WITHOUT_USERAUTH */
} else if (equal(name, "ProxySpec")) { } else if (equal(name, "ProxySpec")) {
if (equal(value, "{")) { if (equal(value, "{")) {
#ifdef DEBUG_OPTS #ifdef DEBUG_OPTS

@ -36,9 +36,11 @@
#include "cert.h" #include "cert.h"
#include "attrib.h" #include "attrib.h"
#ifndef WITHOUT_USERAUTH
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sqlite3.h> #include <sqlite3.h>
#endif /* !WITHOUT_USERAUTH */
/* /*
* Print helper for logging code. * Print helper for logging code.
@ -94,9 +96,11 @@ typedef struct opts {
unsigned int remove_http_referer: 1; unsigned int remove_http_referer: 1;
unsigned int verify_peer: 1; unsigned int verify_peer: 1;
unsigned int allow_wrong_host: 1; unsigned int allow_wrong_host: 1;
#ifndef WITHOUT_USERAUTH
unsigned int user_auth: 1; unsigned int user_auth: 1;
char *user_auth_url; char *user_auth_url;
unsigned int user_timeout; unsigned int user_timeout;
#endif /* !WITHOUT_USERAUTH */
unsigned int validate_proto : 1; unsigned int validate_proto : 1;
unsigned int max_http_header_size; unsigned int max_http_header_size;
struct passsite *passsites; struct passsite *passsites;
@ -137,9 +141,11 @@ typedef struct passsite {
char *site; char *site;
// Filter definition fields // Filter definition fields
char *ip; char *ip;
#ifndef WITHOUT_USERAUTH
char *user; char *user;
unsigned int all : 1; /* 1 for all users */ unsigned int all : 1; /* 1 for all users */
char *keyword; char *keyword;
#endif /* !WITHOUT_USERAUTH */
struct passsite *next; struct passsite *next;
} passsite_t; } passsite_t;
@ -190,9 +196,11 @@ struct global {
unsigned int stats_period; unsigned int stats_period;
unsigned int statslog: 1; unsigned int statslog: 1;
unsigned int log_stats: 1; unsigned int log_stats: 1;
#ifndef WITHOUT_USERAUTH
char *userdb_path; char *userdb_path;
sqlite3 *userdb; sqlite3 *userdb;
struct sqlite3_stmt *update_user_atime; struct sqlite3_stmt *update_user_atime;
#endif /* !WITHOUT_USERAUTH */
proxyspec_t *spec; proxyspec_t *spec;
opts_t *opts; opts_t *opts;
@ -210,11 +218,13 @@ struct global {
#endif /* !OPENSSL_NO_ENGINE */ #endif /* !OPENSSL_NO_ENGINE */
}; };
#ifndef WITHOUT_USERAUTH
typedef struct userdbkeys { typedef struct userdbkeys {
char ip[46]; char ip[46];
char user[32]; char user[32];
char ether[18]; char ether[18];
} userdbkeys_t; } userdbkeys_t;
#endif /* !WITHOUT_USERAUTH */
void NORET oom_die(const char *) NONNULL(1); void NORET oom_die(const char *) NONNULL(1);
cert_t *opts_load_cert_chain_key(const char *) NONNULL(1); cert_t *opts_load_cert_chain_key(const char *) NONNULL(1);

@ -66,7 +66,9 @@
#define PRIVSEP_REQ_OPENFILE_P 2 /* open content log file w/mkpath */ #define PRIVSEP_REQ_OPENFILE_P 2 /* open content log file w/mkpath */
#define PRIVSEP_REQ_OPENSOCK 3 /* open socket and pass fd */ #define PRIVSEP_REQ_OPENSOCK 3 /* open socket and pass fd */
#define PRIVSEP_REQ_CERTFILE 4 /* open cert file in certgendir */ #define PRIVSEP_REQ_CERTFILE 4 /* open cert file in certgendir */
#ifndef WITHOUT_USERAUTH
#define PRIVSEP_REQ_UPDATE_ATIME 5 /* update ip,user atime */ #define PRIVSEP_REQ_UPDATE_ATIME 5 /* update ip,user atime */
#endif /* !WITHOUT_USERAUTH */
/* response byte */ /* response byte */
#define PRIVSEP_ANS_SUCCESS 0 /* success */ #define PRIVSEP_ANS_SUCCESS 0 /* success */
#define PRIVSEP_ANS_UNK_CMD 1 /* unknown command */ #define PRIVSEP_ANS_UNK_CMD 1 /* unknown command */
@ -327,6 +329,7 @@ privsep_server_certfile(const char *fn)
return fd; return fd;
} }
#ifndef WITHOUT_USERAUTH
static int WUNRES static int WUNRES
privsep_server_update_atime(global_t *global, const userdbkeys_t *keys) privsep_server_update_atime(global_t *global, const userdbkeys_t *keys)
{ {
@ -350,6 +353,7 @@ privsep_server_update_atime(global_t *global, const userdbkeys_t *keys)
sqlite3_reset(global->update_user_atime); sqlite3_reset(global->update_user_atime);
return 0; return 0;
} }
#endif /* !WITHOUT_USERAUTH */
/* /*
* Handle a single request on a readable server socket. * Handle a single request on a readable server socket.
@ -495,6 +499,7 @@ privsep_server_handle_req(global_t *global, int srvsock)
/* not reached */ /* not reached */
break; break;
} }
#ifndef WITHOUT_USERAUTH
case PRIVSEP_REQ_UPDATE_ATIME: { case PRIVSEP_REQ_UPDATE_ATIME: {
userdbkeys_t arg; userdbkeys_t arg;
@ -531,6 +536,7 @@ privsep_server_handle_req(global_t *global, int srvsock)
/* not reached */ /* not reached */
break; break;
} }
#endif /* !WITHOUT_USERAUTH */
case PRIVSEP_REQ_CERTFILE: { case PRIVSEP_REQ_CERTFILE: {
char *fn; char *fn;
int fd; int fd;
@ -926,6 +932,7 @@ privsep_client_close(int clisock)
return 0; return 0;
} }
#ifndef WITHOUT_USERAUTH
int int
privsep_client_update_atime(int clisock, const userdbkeys_t *keys) privsep_client_update_atime(int clisock, const userdbkeys_t *keys)
{ {
@ -974,6 +981,7 @@ privsep_client_update_atime(int clisock, const userdbkeys_t *keys)
// Does not return an fd // Does not return an fd
return 0; return 0;
} }
#endif /* !WITHOUT_USERAUTH */
/* /*
* Fork and set up privilege separated monitor process. * Fork and set up privilege separated monitor process.

@ -38,7 +38,9 @@ int privsep_client_openfile(int, const char *, int);
int privsep_client_opensock(int, const proxyspec_t *spec); int privsep_client_opensock(int, const proxyspec_t *spec);
int privsep_client_certfile(int, const char *); int privsep_client_certfile(int, const char *);
int privsep_client_close(int); int privsep_client_close(int);
#ifndef WITHOUT_USERAUTH
int privsep_client_update_atime(int, const userdbkeys_t *); int privsep_client_update_atime(int, const userdbkeys_t *);
#endif /* !WITHOUT_USERAUTH */
#endif /* !PRIVSEP_H */ #endif /* !PRIVSEP_H */
/* vim: set noet ft=c: */ /* vim: set noet ft=c: */

@ -135,9 +135,11 @@ protoautossl_bev_readcb_src(struct bufferevent *bev, pxy_conn_ctx_t *ctx)
protoautossl_ctx_t *autossl_ctx = ctx->protoctx->arg; protoautossl_ctx_t *autossl_ctx = ctx->protoctx->arg;
#ifndef WITHOUT_USERAUTH
if (prototcp_try_send_userauth_msg(bev, ctx)) { if (prototcp_try_send_userauth_msg(bev, ctx)) {
return; return;
} }
#endif /* !WITHOUT_USERAUTH */
if (autossl_ctx->clienthello_search) { if (autossl_ctx->clienthello_search) {
if (protoautossl_peek_and_upgrade(ctx) != 0) { if (protoautossl_peek_and_upgrade(ctx) != 0) {
@ -185,9 +187,11 @@ protoautossl_bev_readcb_srvdst(struct bufferevent *bev, pxy_conn_ctx_t *ctx)
{ {
log_finest_va("ENTER, size=%zu", evbuffer_get_length(bufferevent_get_input(bev))); log_finest_va("ENTER, size=%zu", evbuffer_get_length(bufferevent_get_input(bev)));
#ifndef WITHOUT_USERAUTH
if (prototcp_try_send_userauth_msg(ctx->src.bev, ctx)) { if (prototcp_try_send_userauth_msg(ctx->src.bev, ctx)) {
return; return;
} }
#endif /* !WITHOUT_USERAUTH */
// @todo We should validate the response from the server to protect the client, // @todo We should validate the response from the server to protect the client,
// as we do with the smtp protocol, @see protosmtp_bev_readcb_srvdst() // as we do with the smtp protocol, @see protosmtp_bev_readcb_srvdst()
@ -292,9 +296,11 @@ protoautossl_bev_eventcb_connected_srvdst(UNUSED struct bufferevent *bev, pxy_co
return; return;
} }
#ifndef WITHOUT_USERAUTH
if (!ctx->term && !ctx->enomem) { if (!ctx->term && !ctx->enomem) {
pxy_userauth(ctx); pxy_userauth(ctx);
} }
#endif /* !WITHOUT_USERAUTH */
} }
static void NONNULL(1,2) static void NONNULL(1,2)

@ -74,7 +74,11 @@ protohttp_log_connect(pxy_conn_ctx_t *ctx)
#ifdef HAVE_LOCAL_PROCINFO #ifdef HAVE_LOCAL_PROCINFO
" %s" " %s"
#endif /* HAVE_LOCAL_PROCINFO */ #endif /* HAVE_LOCAL_PROCINFO */
"%s user:%s\n", "%s"
#ifndef WITHOUT_USERAUTH
" user:%s"
#endif /* !WITHOUT_USERAUTH */
"\n",
STRORDASH(ctx->srchost_str), STRORDASH(ctx->srchost_str),
STRORDASH(ctx->srcport_str), STRORDASH(ctx->srcport_str),
STRORDASH(ctx->dsthost_str), STRORDASH(ctx->dsthost_str),
@ -87,8 +91,11 @@ protohttp_log_connect(pxy_conn_ctx_t *ctx)
#ifdef HAVE_LOCAL_PROCINFO #ifdef HAVE_LOCAL_PROCINFO
lpi, lpi,
#endif /* HAVE_LOCAL_PROCINFO */ #endif /* HAVE_LOCAL_PROCINFO */
http_ctx->ocsp_denied ? " ocsp:denied" : "", http_ctx->ocsp_denied ? " ocsp:denied" : ""
STRORDASH(ctx->user)); #ifndef WITHOUT_USERAUTH
, STRORDASH(ctx->user)
#endif /* !WITHOUT_USERAUTH */
);
} else { } else {
rv = asprintf(&msg, "CONN: https %s %s %s %s %s %s %s %s %s " rv = asprintf(&msg, "CONN: https %s %s %s %s %s %s %s %s %s "
"sni:%s names:%s " "sni:%s names:%s "
@ -97,7 +104,11 @@ protohttp_log_connect(pxy_conn_ctx_t *ctx)
#ifdef HAVE_LOCAL_PROCINFO #ifdef HAVE_LOCAL_PROCINFO
" %s" " %s"
#endif /* HAVE_LOCAL_PROCINFO */ #endif /* HAVE_LOCAL_PROCINFO */
"%s user:%s\n", "%s"
#ifndef WITHOUT_USERAUTH
" user:%s"
#endif /* !WITHOUT_USERAUTH */
"\n",
STRORDASH(ctx->srchost_str), STRORDASH(ctx->srchost_str),
STRORDASH(ctx->srcport_str), STRORDASH(ctx->srcport_str),
STRORDASH(ctx->dsthost_str), STRORDASH(ctx->dsthost_str),
@ -118,8 +129,11 @@ protohttp_log_connect(pxy_conn_ctx_t *ctx)
#ifdef HAVE_LOCAL_PROCINFO #ifdef HAVE_LOCAL_PROCINFO
lpi, lpi,
#endif /* HAVE_LOCAL_PROCINFO */ #endif /* HAVE_LOCAL_PROCINFO */
http_ctx->ocsp_denied ? " ocsp:denied" : "", http_ctx->ocsp_denied ? " ocsp:denied" : ""
STRORDASH(ctx->user)); #ifndef WITHOUT_USERAUTH
, STRORDASH(ctx->user)
#endif /* !WITHOUT_USERAUTH */
);
} }
if ((rv < 0 ) || !msg) { if ((rv < 0 ) || !msg) {
ctx->enomem = 1; ctx->enomem = 1;
@ -416,6 +430,7 @@ protohttp_filter_request_header(struct evbuffer *inbuf, struct evbuffer *outbuf,
} }
} }
#ifndef WITHOUT_USERAUTH
static char * NONNULL(1,2) static char * NONNULL(1,2)
protohttp_get_url(struct evbuffer *inbuf, pxy_conn_ctx_t *ctx) protohttp_get_url(struct evbuffer *inbuf, pxy_conn_ctx_t *ctx)
{ {
@ -477,6 +492,7 @@ memout:
free(path); free(path);
return url; return url;
} }
#endif /* !WITHOUT_USERAUTH */
// Size = 39 // Size = 39
static char *http_methods[] = { "GET", "PUT", "ICY", "COPY", "HEAD", "LOCK", "MOVE", "POLL", "POST", "BCOPY", "BMOVE", "MKCOL", "TRACE", "LABEL", "MERGE", "DELETE", static char *http_methods[] = { "GET", "PUT", "ICY", "COPY", "HEAD", "LOCK", "MOVE", "POLL", "POST", "BCOPY", "BMOVE", "MKCOL", "TRACE", "LABEL", "MERGE", "DELETE",
@ -542,6 +558,7 @@ protohttp_validate(pxy_conn_ctx_t *ctx)
static void NONNULL(1,2) static void NONNULL(1,2)
protohttp_bev_readcb_src(struct bufferevent *bev, pxy_conn_ctx_t *ctx) protohttp_bev_readcb_src(struct bufferevent *bev, pxy_conn_ctx_t *ctx)
{ {
#ifndef WITHOUT_USERAUTH
static const char redirect[] = static const char redirect[] =
"HTTP/1.1 302 Found\r\n" "HTTP/1.1 302 Found\r\n"
"Location: %s\r\n" "Location: %s\r\n"
@ -550,6 +567,7 @@ protohttp_bev_readcb_src(struct bufferevent *bev, pxy_conn_ctx_t *ctx)
"HTTP/1.1 302 Found\r\n" "HTTP/1.1 302 Found\r\n"
"Location: %s?SSLproxy=%s\r\n" "Location: %s?SSLproxy=%s\r\n"
"\r\n"; "\r\n";
#endif /* !WITHOUT_USERAUTH */
static const char proto_error[] = static const char proto_error[] =
"HTTP/1.1 400 Bad request\r\n" "HTTP/1.1 400 Bad request\r\n"
"Cache-Control: no-cache\r\n" "Cache-Control: no-cache\r\n"
@ -568,6 +586,7 @@ protohttp_bev_readcb_src(struct bufferevent *bev, pxy_conn_ctx_t *ctx)
struct evbuffer *inbuf = bufferevent_get_input(bev); struct evbuffer *inbuf = bufferevent_get_input(bev);
struct evbuffer *outbuf = bufferevent_get_output(ctx->dst.bev); struct evbuffer *outbuf = bufferevent_get_output(ctx->dst.bev);
#ifndef WITHOUT_USERAUTH
if (ctx->spec->opts->user_auth && !ctx->user) { if (ctx->spec->opts->user_auth && !ctx->user) {
log_finest("Redirecting conn"); log_finest("Redirecting conn");
char *url = protohttp_get_url(inbuf, ctx); char *url = protohttp_get_url(inbuf, ctx);
@ -581,6 +600,7 @@ protohttp_bev_readcb_src(struct bufferevent *bev, pxy_conn_ctx_t *ctx)
ctx->sent_userauth_msg = 1; ctx->sent_userauth_msg = 1;
return; return;
} }
#endif /* !WITHOUT_USERAUTH */
if (ctx->spec->opts->validate_proto && !ctx->protoctx->is_valid) { if (ctx->spec->opts->validate_proto && !ctx->protoctx->is_valid) {
http_ctx->seen_bytes += evbuffer_get_length(inbuf); http_ctx->seen_bytes += evbuffer_get_length(inbuf);
@ -874,9 +894,11 @@ protohttp_bev_writecb_src(struct bufferevent *bev, pxy_conn_ctx_t *ctx)
{ {
log_finest("ENTER"); log_finest("ENTER");
#ifndef WITHOUT_USERAUTH
if (prototcp_try_close_unauth_conn(bev, ctx)) { if (prototcp_try_close_unauth_conn(bev, ctx)) {
return; return;
} }
#endif /* !WITHOUT_USERAUTH */
if (prototcp_try_close_protoerror_conn(bev, ctx)) { if (prototcp_try_close_protoerror_conn(bev, ctx)) {
return; return;

@ -129,9 +129,11 @@ protopassthrough_bev_readcb_src(struct bufferevent *bev, pxy_conn_ctx_t *ctx)
return; return;
} }
#ifndef WITHOUT_USERAUTH
if (prototcp_try_send_userauth_msg(bev, ctx)) { if (prototcp_try_send_userauth_msg(bev, ctx)) {
return; return;
} }
#endif /* !WITHOUT_USERAUTH */
evbuffer_add_buffer(bufferevent_get_output(ctx->srvdst.bev), bufferevent_get_input(bev)); evbuffer_add_buffer(bufferevent_get_output(ctx->srvdst.bev), bufferevent_get_input(bev));
pxy_try_set_watermark(bev, ctx, ctx->srvdst.bev); pxy_try_set_watermark(bev, ctx, ctx->srvdst.bev);
@ -157,9 +159,11 @@ protopassthrough_bev_writecb_src(struct bufferevent *bev, pxy_conn_ctx_t *ctx)
{ {
log_finest("ENTER"); log_finest("ENTER");
#ifndef WITHOUT_USERAUTH
if (prototcp_try_close_unauth_conn(bev, ctx)) { if (prototcp_try_close_unauth_conn(bev, ctx)) {
return; return;
} }
#endif /* !WITHOUT_USERAUTH */
// @attention srvdst.bev may be NULL // @attention srvdst.bev may be NULL
if (ctx->srvdst.closed) { if (ctx->srvdst.closed) {
@ -222,9 +226,11 @@ protopassthrough_bev_eventcb_connected_srvdst(struct bufferevent *bev, pxy_conn_
return; return;
} }
#ifndef WITHOUT_USERAUTH
if (!ctx->term && !ctx->enomem) { if (!ctx->term && !ctx->enomem) {
pxy_userauth(ctx); pxy_userauth(ctx);
} }
#endif /* !WITHOUT_USERAUTH */
} }
static void NONNULL(1,2) static void NONNULL(1,2)

@ -185,9 +185,11 @@ protosmtp_bev_readcb_srvdst(struct bufferevent *bev, pxy_conn_ctx_t *ctx)
return; return;
} }
#ifndef WITHOUT_USERAUTH
if (prototcp_try_send_userauth_msg(ctx->src.bev, ctx)) { if (prototcp_try_send_userauth_msg(ctx->src.bev, ctx)) {
return; return;
} }
#endif /* !WITHOUT_USERAUTH */
struct evbuffer *inbuf = bufferevent_get_input(bev); struct evbuffer *inbuf = bufferevent_get_input(bev);
struct evbuffer *outbuf = bufferevent_get_output(ctx->src.bev); struct evbuffer *outbuf = bufferevent_get_output(ctx->src.bev);

@ -581,10 +581,18 @@ protossl_srccert_create(pxy_conn_ctx_t *ctx)
static int NONNULL(1,2) static int NONNULL(1,2)
protossl_pass_user(pxy_conn_ctx_t *ctx, passsite_t *passsite) protossl_pass_user(pxy_conn_ctx_t *ctx, passsite_t *passsite)
{ {
#ifndef WITHOUT_USERAUTH
log_finest_va("ENTER, %s, %s, %s, %s", passsite->site, STRORDASH(passsite->ip), passsite->all ? "*" : STRORDASH(passsite->user), STRORDASH(passsite->keyword)); log_finest_va("ENTER, %s, %s, %s, %s", passsite->site, STRORDASH(passsite->ip), passsite->all ? "*" : STRORDASH(passsite->user), STRORDASH(passsite->keyword));
#else /* WITHOUT_USERAUTH */
log_finest_va("ENTER, %s, %s", passsite->site, STRORDASH(passsite->ip));
#endif /* WITHOUT_USERAUTH */
// No filter or * (all) without desc keyword defined // No filter or * (all) without desc keyword defined
if (!passsite->ip && !passsite->user && !passsite->keyword) { if (!passsite->ip
#ifndef WITHOUT_USERAUTH
&& !passsite->user && !passsite->keyword
#endif /* !WITHOUT_USERAUTH */
) {
return 1; return 1;
} }
@ -595,14 +603,16 @@ protossl_pass_user(pxy_conn_ctx_t *ctx, passsite_t *passsite)
return 1; return 1;
} }
#ifndef WITHOUT_USERAUTH
log_finest_va("Filter user: %s, %s", STRORDASH(ctx->user), STRORDASH(ctx->desc)); log_finest_va("Filter user: %s, %s", STRORDASH(ctx->user), STRORDASH(ctx->desc));
// Make sure ctx->user and ctx->desc are set, otherwise if the user did not log in yet, they may be NULL // Make sure ctx->user and ctx->desc are set, otherwise if the user has not logged in yet, they may be NULL
// User and/or description keyword filters defined // User and/or description keyword filters defined
if (ctx->spec->opts->user_auth && (passsite->all || (passsite->user && ctx->user && !strcmp(ctx->user, passsite->user))) && if (ctx->spec->opts->user_auth && (passsite->all || (passsite->user && ctx->user && !strcmp(ctx->user, passsite->user))) &&
(!passsite->keyword || (ctx->desc && strcasestr(ctx->desc, passsite->keyword)))) { (!passsite->keyword || (ctx->desc && strcasestr(ctx->desc, passsite->keyword)))) {
return 1; return 1;
} }
#endif /* !WITHOUT_USERAUTH */
return 0; return 0;
} }
@ -720,8 +730,12 @@ protossl_srcssl_create(pxy_conn_ctx_t *ctx, SSL *origssl)
while (passsite) { while (passsite) {
if (protossl_pass_user(ctx, passsite) && protossl_pass_site(ctx, passsite->site)) { if (protossl_pass_user(ctx, passsite) && protossl_pass_site(ctx, passsite->site)) {
// Do not print the surrounding slashes // Do not print the surrounding slashes
#ifndef WITHOUT_USERAUTH
log_err_level_printf(LOG_WARNING, "Found pass site: %.*s for user %s and keyword %s\n", (int)strlen(passsite->site) - 2, passsite->site + 1, log_err_level_printf(LOG_WARNING, "Found pass site: %.*s for user %s and keyword %s\n", (int)strlen(passsite->site) - 2, passsite->site + 1,
passsite->ip ? passsite->ip : (passsite->all ? "*" : STRORDASH(passsite->user)), STRORDASH(passsite->keyword)); passsite->ip ? passsite->ip : (passsite->all ? "*" : STRORDASH(passsite->user)), STRORDASH(passsite->keyword));
#else /* WITHOUT_USERAUTH */
log_err_level_printf(LOG_WARNING, "Found pass site: %.*s for ip %s\n", (int)strlen(passsite->site) - 2, passsite->site + 1, STRORDASH(passsite->ip));
#endif /* WITHOUT_USERAUTH */
cert_free(cert); cert_free(cert);
// Differentiate passsite from passthrough option by raising the passsite flag // Differentiate passsite from passthrough option by raising the passsite flag
ctx->sslctx->passsite = 1; ctx->sslctx->passsite = 1;
@ -1521,9 +1535,11 @@ protossl_bev_eventcb_connected_srvdst(UNUSED struct bufferevent *bev, pxy_conn_c
return; return;
} }
#ifndef WITHOUT_USERAUTH
if (!ctx->term && !ctx->enomem) { if (!ctx->term && !ctx->enomem) {
pxy_userauth(ctx); pxy_userauth(ctx);
} }
#endif /* !WITHOUT_USERAUTH */
} }
static void NONNULL(1,2) static void NONNULL(1,2)

@ -214,6 +214,7 @@ prototcp_init_conn(UNUSED evutil_socket_t fd, UNUSED short what, void *arg)
pxy_conn_connect(ctx); pxy_conn_connect(ctx);
} }
#ifndef WITHOUT_USERAUTH
int int
prototcp_try_send_userauth_msg(struct bufferevent *bev, pxy_conn_ctx_t *ctx) prototcp_try_send_userauth_msg(struct bufferevent *bev, pxy_conn_ctx_t *ctx)
{ {
@ -226,6 +227,7 @@ prototcp_try_send_userauth_msg(struct bufferevent *bev, pxy_conn_ctx_t *ctx)
} }
return 0; return 0;
} }
#endif /* !WITHOUT_USERAUTH */
static int NONNULL(1,2,3,4) static int NONNULL(1,2,3,4)
prototcp_try_validate_proto(struct bufferevent *bev, pxy_conn_ctx_t *ctx, struct evbuffer *inbuf, struct evbuffer *outbuf) prototcp_try_validate_proto(struct bufferevent *bev, pxy_conn_ctx_t *ctx, struct evbuffer *inbuf, struct evbuffer *outbuf)
@ -266,9 +268,11 @@ prototcp_bev_readcb_src(struct bufferevent *bev, pxy_conn_ctx_t *ctx)
return; return;
} }
#ifndef WITHOUT_USERAUTH
if (prototcp_try_send_userauth_msg(bev, ctx)) { if (prototcp_try_send_userauth_msg(bev, ctx)) {
return; return;
} }
#endif /* !WITHOUT_USERAUTH */
struct evbuffer *inbuf = bufferevent_get_input(bev); struct evbuffer *inbuf = bufferevent_get_input(bev);
struct evbuffer *outbuf = bufferevent_get_output(ctx->dst.bev); struct evbuffer *outbuf = bufferevent_get_output(ctx->dst.bev);
@ -369,6 +373,7 @@ prototcp_bev_readcb_dst_child(struct bufferevent *bev, pxy_conn_child_ctx_t *ctx
pxy_try_set_watermark(bev, ctx->conn, ctx->src.bev); pxy_try_set_watermark(bev, ctx->conn, ctx->src.bev);
} }
#ifndef WITHOUT_USERAUTH
int int
prototcp_try_close_unauth_conn(struct bufferevent *bev, pxy_conn_ctx_t *ctx) prototcp_try_close_unauth_conn(struct bufferevent *bev, pxy_conn_ctx_t *ctx)
{ {
@ -386,6 +391,7 @@ prototcp_try_close_unauth_conn(struct bufferevent *bev, pxy_conn_ctx_t *ctx)
} }
return 0; return 0;
} }
#endif /* !WITHOUT_USERAUTH */
int int
prototcp_try_close_protoerror_conn(struct bufferevent *bev, pxy_conn_ctx_t *ctx) prototcp_try_close_protoerror_conn(struct bufferevent *bev, pxy_conn_ctx_t *ctx)
@ -408,9 +414,11 @@ prototcp_bev_writecb_src(struct bufferevent *bev, pxy_conn_ctx_t *ctx)
{ {
log_finest("ENTER"); log_finest("ENTER");
#ifndef WITHOUT_USERAUTH
if (prototcp_try_close_unauth_conn(bev, ctx)) { if (prototcp_try_close_unauth_conn(bev, ctx)) {
return; return;
} }
#endif /* !WITHOUT_USERAUTH */
if (prototcp_try_close_protoerror_conn(bev, ctx)) { if (prototcp_try_close_protoerror_conn(bev, ctx)) {
return; return;
@ -522,9 +530,11 @@ prototcp_bev_eventcb_connected_srvdst(UNUSED struct bufferevent *bev, pxy_conn_c
return; return;
} }
#ifndef WITHOUT_USERAUTH
if (!ctx->term && !ctx->enomem) { if (!ctx->term && !ctx->enomem) {
pxy_userauth(ctx); pxy_userauth(ctx);
} }
#endif /* !WITHOUT_USERAUTH */
} }
void void

@ -34,8 +34,10 @@
void prototcp_init_conn(evutil_socket_t, short, void *); void prototcp_init_conn(evutil_socket_t, short, void *);
#ifndef WITHOUT_USERAUTH
int prototcp_try_send_userauth_msg(struct bufferevent *, pxy_conn_ctx_t *) NONNULL(1,2); int prototcp_try_send_userauth_msg(struct bufferevent *, pxy_conn_ctx_t *) NONNULL(1,2);
int prototcp_try_close_unauth_conn(struct bufferevent *, pxy_conn_ctx_t *) NONNULL(1,2); int prototcp_try_close_unauth_conn(struct bufferevent *, pxy_conn_ctx_t *) NONNULL(1,2);
#endif /* !WITHOUT_USERAUTH */
int prototcp_try_close_protoerror_conn(struct bufferevent *, pxy_conn_ctx_t *) NONNULL(1,2); int prototcp_try_close_protoerror_conn(struct bufferevent *, pxy_conn_ctx_t *) NONNULL(1,2);
void prototcp_bev_readcb_src(struct bufferevent *, pxy_conn_ctx_t *) NONNULL(1,2); void prototcp_bev_readcb_src(struct bufferevent *, pxy_conn_ctx_t *) NONNULL(1,2);

@ -148,8 +148,11 @@ proxy_setup_proto(pxy_conn_ctx_t *ctx)
pxy_conn_ctx_t * pxy_conn_ctx_t *
proxy_conn_ctx_new(evutil_socket_t fd, proxy_conn_ctx_new(evutil_socket_t fd,
pxy_thrmgr_ctx_t *thrmgr, pxy_thrmgr_ctx_t *thrmgr,
proxyspec_t *spec, global_t *global, proxyspec_t *spec, global_t *global
evutil_socket_t clisock) #ifndef WITHOUT_USERAUTH
, evutil_socket_t clisock
#endif /* !WITHOUT_USERAUTH */
)
{ {
log_finest_main_va("ENTER, fd=%d", fd); log_finest_main_va("ENTER, fd=%d", fd);
@ -175,7 +178,9 @@ proxy_conn_ctx_new(evutil_socket_t fd,
} }
ctx->global = global; ctx->global = global;
#ifndef WITHOUT_USERAUTH
ctx->clisock = clisock; ctx->clisock = clisock;
#endif /* !WITHOUT_USERAUTH */
#ifdef HAVE_LOCAL_PROCINFO #ifdef HAVE_LOCAL_PROCINFO
ctx->lproc.pid = -1; ctx->lproc.pid = -1;
@ -229,7 +234,11 @@ proxy_listener_acceptcb(UNUSED struct evconnlistener *listener,
log_finest_main_va("ENTER, fd=%d", fd); log_finest_main_va("ENTER, fd=%d", fd);
/* create per connection state */ /* create per connection state */
pxy_conn_ctx_t *ctx = proxy_conn_ctx_new(fd, lctx->thrmgr, lctx->spec, lctx->global, lctx->clisock); pxy_conn_ctx_t *ctx = proxy_conn_ctx_new(fd, lctx->thrmgr, lctx->spec, lctx->global
#ifndef WITHOUT_USERAUTH
, lctx->clisock
#endif /* !WITHOUT_USERAUTH */
);
if (!ctx) { if (!ctx) {
log_err_level_printf(LOG_CRIT, "Error allocating ctx memory\n"); log_err_level_printf(LOG_CRIT, "Error allocating ctx memory\n");
evutil_closesocket(fd); evutil_closesocket(fd);
@ -319,7 +328,9 @@ proxy_listener_setup(struct event_base *evbase, pxy_thrmgr_ctx_t *thrmgr,
return NULL; return NULL;
} }
#ifndef WITHOUT_USERAUTH
lctx->clisock = clisock; lctx->clisock = clisock;
#endif /* !WITHOUT_USERAUTH */
// @attention Do not pass NULL as user-supplied pointer // @attention Do not pass NULL as user-supplied pointer
lctx->evcl = evconnlistener_new(evbase, proxy_listener_acceptcb, lctx->evcl = evconnlistener_new(evbase, proxy_listener_acceptcb,
@ -490,8 +501,10 @@ proxy_new(global_t *global, int clisock)
goto leave4; goto leave4;
evtimer_add(ctx->gcev, &gc_delay); evtimer_add(ctx->gcev, &gc_delay);
// @attention Do not close privsep sock, we use it to update user atime // @attention Do not close privsep sock if the USERAUTH feature is compiled in, we use it to update user atime
//privsep_client_close(clisock); #ifdef WITHOUT_USERAUTH
privsep_client_close(clisock);
#endif /* !WITHOUT_USERAUTH */
return ctx; return ctx;
leave4: leave4:

@ -44,7 +44,9 @@ typedef struct proxy_listener_ctx {
pxy_thrmgr_ctx_t *thrmgr; pxy_thrmgr_ctx_t *thrmgr;
proxyspec_t *spec; proxyspec_t *spec;
global_t *global; global_t *global;
#ifndef WITHOUT_USERAUTH
evutil_socket_t clisock; evutil_socket_t clisock;
#endif /* !WITHOUT_USERAUTH */
struct evconnlistener *evcl; struct evconnlistener *evcl;
struct proxy_listener_ctx *next; struct proxy_listener_ctx *next;
} proxy_listener_ctx_t; } proxy_listener_ctx_t;
@ -55,7 +57,11 @@ void proxy_loopbreak(proxy_ctx_t *, int) NONNULL(1);
void proxy_free(proxy_ctx_t *) NONNULL(1); void proxy_free(proxy_ctx_t *) NONNULL(1);
void proxy_listener_errorcb(struct evconnlistener *, UNUSED void *); void proxy_listener_errorcb(struct evconnlistener *, UNUSED void *);
pxy_conn_ctx_t *proxy_conn_ctx_new(evutil_socket_t, pxy_thrmgr_ctx_t *, proxyspec_t *, global_t *, evutil_socket_t) MALLOC NONNULL(2,3,4); pxy_conn_ctx_t *proxy_conn_ctx_new(evutil_socket_t, pxy_thrmgr_ctx_t *, proxyspec_t *, global_t *
#ifndef WITHOUT_USERAUTH
, evutil_socket_t
#endif /* !WITHOUT_USERAUTH */
) MALLOC NONNULL(2,3,4);
#endif /* !PROXY_H */ #endif /* !PROXY_H */
/* vim: set noet ft=c: */ /* vim: set noet ft=c: */

@ -309,6 +309,7 @@ pxy_conn_ctx_free(pxy_conn_ctx_t *ctx, int by_requestor)
} }
} }
#ifndef WITHOUT_USERAUTH
if (ctx->spec->opts->user_auth && ctx->srchost_str && ctx->user && ctx->ether) { if (ctx->spec->opts->user_auth && ctx->srchost_str && ctx->user && ctx->ether) {
// Update userdb atime if idle time is more than 50% of user timeout, which is expected to reduce update frequency // Update userdb atime if idle time is more than 50% of user timeout, which is expected to reduce update frequency
unsigned int idletime = ctx->idletime + (time(NULL) - ctx->ctime); unsigned int idletime = ctx->idletime + (time(NULL) - ctx->ctime);
@ -330,6 +331,7 @@ pxy_conn_ctx_free(pxy_conn_ctx_t *ctx, int by_requestor)
log_finest_va("Will not update user atime, idletime=%u", idletime); log_finest_va("Will not update user atime, idletime=%u", idletime);
} }
} }
#endif /* !WITHOUT_USERAUTH */
pxy_thr_detach(ctx); pxy_thr_detach(ctx);
@ -368,6 +370,7 @@ pxy_conn_ctx_free(pxy_conn_ctx_t *ctx, int by_requestor)
} }
free(ctx->protoctx); free(ctx->protoctx);
#ifndef WITHOUT_USERAUTH
if (ctx->user) { if (ctx->user) {
free(ctx->user); free(ctx->user);
} }
@ -377,6 +380,7 @@ pxy_conn_ctx_free(pxy_conn_ctx_t *ctx, int by_requestor)
if (ctx->desc) { if (ctx->desc) {
free(ctx->desc); free(ctx->desc);
} }
#endif /* !WITHOUT_USERAUTH */
free(ctx); free(ctx);
} }
@ -454,16 +458,22 @@ pxy_log_connect_nonhttp(pxy_conn_ctx_t *ctx)
#ifdef HAVE_LOCAL_PROCINFO #ifdef HAVE_LOCAL_PROCINFO
" %s" " %s"
#endif /* HAVE_LOCAL_PROCINFO */ #endif /* HAVE_LOCAL_PROCINFO */
" user:%s\n", #ifndef WITHOUT_USERAUTH
" user:%s"
#endif /* !WITHOUT_USERAUTH */
"\n",
ctx->proto == PROTO_PASSTHROUGH ? "passthrough" : (ctx->proto == PROTO_POP3 ? "pop3" : (ctx->proto == PROTO_SMTP ? "smtp" : "tcp")), ctx->proto == PROTO_PASSTHROUGH ? "passthrough" : (ctx->proto == PROTO_POP3 ? "pop3" : (ctx->proto == PROTO_SMTP ? "smtp" : "tcp")),
STRORDASH(ctx->srchost_str), STRORDASH(ctx->srchost_str),
STRORDASH(ctx->srcport_str), STRORDASH(ctx->srcport_str),
STRORDASH(ctx->dsthost_str), STRORDASH(ctx->dsthost_str),
STRORDASH(ctx->dstport_str), STRORDASH(ctx->dstport_str)
#ifdef HAVE_LOCAL_PROCINFO #ifdef HAVE_LOCAL_PROCINFO
lpi, , lpi
#endif /* HAVE_LOCAL_PROCINFO */ #endif /* HAVE_LOCAL_PROCINFO */
STRORDASH(ctx->user)); #ifndef WITHOUT_USERAUTH
, STRORDASH(ctx->user)
#endif /* !WITHOUT_USERAUTH */
);
} else { } else {
rv = asprintf(&msg, "CONN: %s %s %s %s %s " rv = asprintf(&msg, "CONN: %s %s %s %s %s "
"sni:%s names:%s " "sni:%s names:%s "
@ -472,7 +482,10 @@ pxy_log_connect_nonhttp(pxy_conn_ctx_t *ctx)
#ifdef HAVE_LOCAL_PROCINFO #ifdef HAVE_LOCAL_PROCINFO
" %s" " %s"
#endif /* HAVE_LOCAL_PROCINFO */ #endif /* HAVE_LOCAL_PROCINFO */
" user:%s\n", #ifndef WITHOUT_USERAUTH
" user:%s"
#endif /* !WITHOUT_USERAUTH */
"\n",
ctx->proto == PROTO_AUTOSSL ? "autossl" : (ctx->proto == PROTO_POP3S ? "pop3s" : (ctx->proto == PROTO_SMTPS ? "smtps" : "ssl")), ctx->proto == PROTO_AUTOSSL ? "autossl" : (ctx->proto == PROTO_POP3S ? "pop3s" : (ctx->proto == PROTO_SMTPS ? "smtps" : "ssl")),
STRORDASH(ctx->srchost_str), STRORDASH(ctx->srchost_str),
STRORDASH(ctx->srcport_str), STRORDASH(ctx->srcport_str),
@ -485,11 +498,14 @@ pxy_log_connect_nonhttp(pxy_conn_ctx_t *ctx)
STRORDASH(ctx->sslctx->srvdst_ssl_version), STRORDASH(ctx->sslctx->srvdst_ssl_version),
STRORDASH(ctx->sslctx->srvdst_ssl_cipher), STRORDASH(ctx->sslctx->srvdst_ssl_cipher),
STRORDASH(ctx->sslctx->origcrtfpr), STRORDASH(ctx->sslctx->origcrtfpr),
STRORDASH(ctx->sslctx->usedcrtfpr), STRORDASH(ctx->sslctx->usedcrtfpr)
#ifdef HAVE_LOCAL_PROCINFO #ifdef HAVE_LOCAL_PROCINFO
lpi, , lpi
#endif /* HAVE_LOCAL_PROCINFO */ #endif /* HAVE_LOCAL_PROCINFO */
STRORDASH(ctx->user)); #ifndef WITHOUT_USERAUTH
, STRORDASH(ctx->user)
#endif /* !WITHOUT_USERAUTH */
);
} }
if ((rv < 0) || !msg) { if ((rv < 0) || !msg) {
ctx->enomem = 1; ctx->enomem = 1;
@ -1152,16 +1168,22 @@ pxy_setup_child_listener(pxy_conn_ctx_t *ctx)
return -1; return -1;
} }
#ifndef WITHOUT_USERAUTH
int user_len = 0; int user_len = 0;
if (ctx->spec->opts->user_auth && ctx->user) { if (ctx->spec->opts->user_auth && ctx->user) {
// +1 for comma // +1 for comma
user_len = strlen(ctx->user) + 1; user_len = strlen(ctx->user) + 1;
} }
#endif /* !WITHOUT_USERAUTH */
// SSLproxy: [127.0.0.1]:34649,[192.168.3.24]:47286,[74.125.206.108]:465,s,soner // SSLproxy: [127.0.0.1]:34649,[192.168.3.24]:47286,[74.125.206.108]:465,s,soner
// SSLproxy: + + [ + addr + ] + : + p + , + [ + srchost_str + ] + : + srcport_str + , + [ + dsthost_str + ] + : + dstport_str + , + s + , + user // SSLproxy: + + [ + addr + ] + : + p + , + [ + srchost_str + ] + : + srcport_str + , + [ + dsthost_str + ] + : + dstport_str + , + s + , + user
// SSLPROXY_KEY_LEN + 1 + 1 + strlen(addr) + 1 + 1 + port_len + 1 + 1 + strlen(ctx->srchost_str) + 1 + 1 + strlen(ctx->srcport_str) + 1 + 1 + strlen(ctx->dsthost_str) + 1 + 1 + strlen(ctx->dstport_str) + 1 + 1 + user_len // SSLPROXY_KEY_LEN + 1 + 1 + strlen(addr) + 1 + 1 + port_len + 1 + 1 + strlen(ctx->srchost_str) + 1 + 1 + strlen(ctx->srcport_str) + 1 + 1 + strlen(ctx->dsthost_str) + 1 + 1 + strlen(ctx->dstport_str) + 1 + 1 + user_len
ctx->sslproxy_header_len = SSLPROXY_KEY_LEN + strlen(addr) + port_len + strlen(ctx->srchost_str) + strlen(ctx->srcport_str) + strlen(ctx->dsthost_str) + strlen(ctx->dstport_str) + 14 + user_len; ctx->sslproxy_header_len = SSLPROXY_KEY_LEN + strlen(addr) + port_len + strlen(ctx->srchost_str) + strlen(ctx->srcport_str) + strlen(ctx->dsthost_str) + strlen(ctx->dstport_str) + 14
#ifndef WITHOUT_USERAUTH
+ user_len
#endif /* !WITHOUT_USERAUTH */
;
// +1 for NULL // +1 for NULL
ctx->sslproxy_header = malloc(ctx->sslproxy_header_len + 1); ctx->sslproxy_header = malloc(ctx->sslproxy_header_len + 1);
@ -1172,9 +1194,17 @@ pxy_setup_child_listener(pxy_conn_ctx_t *ctx)
// printf(3): "snprintf() will write at most size-1 of the characters (the size'th character then gets the terminating NULL)" // printf(3): "snprintf() will write at most size-1 of the characters (the size'th character then gets the terminating NULL)"
// So, +1 for NULL // So, +1 for NULL
if (snprintf(ctx->sslproxy_header, ctx->sslproxy_header_len + 1, "%s [%s]:%u,[%s]:%s,[%s]:%s,%s%s%s", if (snprintf(ctx->sslproxy_header, ctx->sslproxy_header_len + 1, "%s [%s]:%u,[%s]:%s,[%s]:%s,%s"
#ifndef WITHOUT_USERAUTH
"%s%s"
#endif /* !WITHOUT_USERAUTH */
,
SSLPROXY_KEY, addr, port, STRORNONE(ctx->srchost_str), STRORNONE(ctx->srcport_str), SSLPROXY_KEY, addr, port, STRORNONE(ctx->srchost_str), STRORNONE(ctx->srcport_str),
STRORNONE(ctx->dsthost_str), STRORNONE(ctx->dstport_str), ctx->spec->ssl ? "s":"p", user_len ? "," : "", user_len ? ctx->user : "") < 0) { STRORNONE(ctx->dsthost_str), STRORNONE(ctx->dstport_str), ctx->spec->ssl ? "s":"p"
#ifndef WITHOUT_USERAUTH
, user_len ? "," : "", user_len ? ctx->user : ""
#endif /* !WITHOUT_USERAUTH */
) < 0) {
// ctx->sslproxy_header is freed by pxy_conn_ctx_free() // ctx->sslproxy_header is freed by pxy_conn_ctx_free()
pxy_conn_term(ctx, 1); pxy_conn_term(ctx, 1);
return -1; return -1;
@ -1547,6 +1577,7 @@ pxy_conn_connect(pxy_conn_ctx_t *ctx)
} }
} }
#ifndef WITHOUT_USERAUTH
#if defined(__OpenBSD__) || defined(__linux__) #if defined(__OpenBSD__) || defined(__linux__)
static void static void
identify_user(UNUSED evutil_socket_t fd, UNUSED short what, void *arg) identify_user(UNUSED evutil_socket_t fd, UNUSED short what, void *arg)
@ -1816,6 +1847,7 @@ pxy_userauth(pxy_conn_ctx_t *ctx)
} }
return 0; return 0;
} }
#endif /* !WITHOUT_USERAUTH */
int int
pxy_conn_init(pxy_conn_ctx_t *ctx) pxy_conn_init(pxy_conn_ctx_t *ctx)

@ -52,7 +52,9 @@
#define SSLPROXY_KEY "SSLproxy:" #define SSLPROXY_KEY "SSLproxy:"
#define SSLPROXY_KEY_LEN strlen(SSLPROXY_KEY) #define SSLPROXY_KEY_LEN strlen(SSLPROXY_KEY)
#ifndef WITHOUT_USERAUTH
#define USERAUTH_MSG "You must authenticate to access the Internet at %s\r\n" #define USERAUTH_MSG "You must authenticate to access the Internet at %s\r\n"
#endif /* !WITHOUT_USERAUTH */
#define PROTOERROR_MSG "Connection is terminated due to protocol error\r\n" #define PROTOERROR_MSG "Connection is terminated due to protocol error\r\n"
#define PROTOERROR_MSG_LEN strlen(PROTOERROR_MSG) #define PROTOERROR_MSG_LEN strlen(PROTOERROR_MSG)
@ -250,8 +252,10 @@ struct pxy_conn_ctx {
evutil_socket_t dst_fd; evutil_socket_t dst_fd;
evutil_socket_t srvdst_fd; evutil_socket_t srvdst_fd;
#ifndef WITHOUT_USERAUTH
// Privsep socket to update user atime // Privsep socket to update user atime
evutil_socket_t clisock; evutil_socket_t clisock;
#endif /* !WITHOUT_USERAUTH */
// fd of event listener for children, explicitly closed on error (not for stats only) // fd of event listener for children, explicitly closed on error (not for stats only)
evutil_socket_t child_fd; evutil_socket_t child_fd;
@ -289,6 +293,7 @@ struct pxy_conn_ctx {
// Expired conns are link-listed using this pointer, a temporary list used in conn thr timercb only // Expired conns are link-listed using this pointer, a temporary list used in conn thr timercb only
pxy_conn_ctx_t *next_expired; pxy_conn_ctx_t *next_expired;
#ifndef WITHOUT_USERAUTH
// Number of times we try to acquire user db before giving up // Number of times we try to acquire user db before giving up
unsigned int identify_user_count; unsigned int identify_user_count;
// User owner of conn // User owner of conn
@ -301,6 +306,7 @@ struct pxy_conn_ctx {
char *desc; char *desc;
// We send redirect/error msg to client if user auth or proto validation fails // We send redirect/error msg to client if user auth or proto validation fails
unsigned int sent_userauth_msg : 1; /* 1 until error msg is sent */ unsigned int sent_userauth_msg : 1; /* 1 until error msg is sent */
#endif /* !WITHOUT_USERAUTH */
unsigned int sent_protoerror_msg : 1; /* 1 until error msg is sent */ unsigned int sent_protoerror_msg : 1; /* 1 until error msg is sent */
#ifdef HAVE_LOCAL_PROCINFO #ifdef HAVE_LOCAL_PROCINFO
@ -400,7 +406,9 @@ void pxy_bev_writecb_child(struct bufferevent *, void *);
void pxy_bev_eventcb_child(struct bufferevent *, short, void *); void pxy_bev_eventcb_child(struct bufferevent *, short, void *);
void pxy_conn_connect(pxy_conn_ctx_t *) NONNULL(1); void pxy_conn_connect(pxy_conn_ctx_t *) NONNULL(1);
#ifndef WITHOUT_USERAUTH
int pxy_userauth(pxy_conn_ctx_t *) NONNULL(1); int pxy_userauth(pxy_conn_ctx_t *) NONNULL(1);
#endif /* !WITHOUT_USERAUTH */
void pxy_conn_setup(evutil_socket_t, struct sockaddr *, int, void pxy_conn_setup(evutil_socket_t, struct sockaddr *, int,
pxy_thrmgr_ctx_t *, proxyspec_t *, global_t *, pxy_thrmgr_ctx_t *, proxyspec_t *, global_t *,
evutil_socket_t) evutil_socket_t)

@ -132,18 +132,33 @@ pxy_thr_get_expired_conns(pxy_thr_ctx_t *tctx, pxy_conn_ctx_t **expired_conns)
time_t atime = now - ctx->atime; time_t atime = now - ctx->atime;
time_t ctime = now - ctx->ctime; time_t ctime = now - ctx->ctime;
#ifndef WITHOUT_USERAUTH
log_finest_main_va("thr=%d, id=%llu, fd=%d, child_fd=%d, dst=%d, srvdst=%d, child_src=%d, child_dst=%d, p=%d-%d-%d c=%d-%d, ce=%d cc=%d, at=%lld ct=%lld, src_addr=%s:%s, dst_addr=%s:%s, user=%s, valid=%d", log_finest_main_va("thr=%d, id=%llu, fd=%d, child_fd=%d, dst=%d, srvdst=%d, child_src=%d, child_dst=%d, p=%d-%d-%d c=%d-%d, ce=%d cc=%d, at=%lld ct=%lld, src_addr=%s:%s, dst_addr=%s:%s, user=%s, valid=%d",
tctx->id, ctx->id, ctx->fd, ctx->child_fd, ctx->dst_fd, ctx->srvdst_fd, ctx->child_src_fd, ctx->child_dst_fd, tctx->id, ctx->id, ctx->fd, ctx->child_fd, ctx->dst_fd, ctx->srvdst_fd, ctx->child_src_fd, ctx->child_dst_fd,
ctx->src.closed, ctx->dst.closed, ctx->srvdst.closed, ctx->children ? ctx->children->src.closed : 0, ctx->children ? ctx->children->dst.closed : 0, ctx->src.closed, ctx->dst.closed, ctx->srvdst.closed, ctx->children ? ctx->children->src.closed : 0, ctx->children ? ctx->children->dst.closed : 0,
ctx->children ? 1:0, ctx->child_count, (long long)atime, (long long)ctime, ctx->children ? 1:0, ctx->child_count, (long long)atime, (long long)ctime,
STRORDASH(ctx->srchost_str), STRORDASH(ctx->srcport_str), STRORDASH(ctx->dsthost_str), STRORDASH(ctx->dstport_str), STRORDASH(ctx->srchost_str), STRORDASH(ctx->srcport_str), STRORDASH(ctx->dsthost_str), STRORDASH(ctx->dstport_str),
STRORDASH(ctx->user), ctx->protoctx->is_valid); STRORDASH(ctx->user), ctx->protoctx->is_valid);
#else /* WITHOUT_USERAUTH */
log_finest_main_va("thr=%d, id=%llu, fd=%d, child_fd=%d, dst=%d, srvdst=%d, child_src=%d, child_dst=%d, p=%d-%d-%d c=%d-%d, ce=%d cc=%d, at=%lld ct=%lld, src_addr=%s:%s, dst_addr=%s:%s, valid=%d",
tctx->id, ctx->id, ctx->fd, ctx->child_fd, ctx->dst_fd, ctx->srvdst_fd, ctx->child_src_fd, ctx->child_dst_fd,
ctx->src.closed, ctx->dst.closed, ctx->srvdst.closed, ctx->children ? ctx->children->src.closed : 0, ctx->children ? ctx->children->dst.closed : 0,
ctx->children ? 1:0, ctx->child_count, (long long)atime, (long long)ctime,
STRORDASH(ctx->srchost_str), STRORDASH(ctx->srcport_str), STRORDASH(ctx->dsthost_str), STRORDASH(ctx->dstport_str), ctx->protoctx->is_valid);
#endif /* WITHOUT_USERAUTH */
char *msg; char *msg;
if (asprintf(&msg, "EXPIRED: atime=%lld, ctime=%lld, src_addr=%s:%s, dst_addr=%s:%s, user=%s, valid=%d\n", if (asprintf(&msg, "EXPIRED: atime=%lld, ctime=%lld, src_addr=%s:%s, dst_addr=%s:%s, "
#ifndef WITHOUT_USERAUTH
"user=%s, "
#endif /* !WITHOUT_USERAUTH */
"valid=%d\n",
(long long)atime, (long long)ctime, (long long)atime, (long long)ctime,
STRORDASH(ctx->srchost_str), STRORDASH(ctx->srcport_str), STRORDASH(ctx->dsthost_str), STRORDASH(ctx->dstport_str), STRORDASH(ctx->srchost_str), STRORDASH(ctx->srcport_str), STRORDASH(ctx->dsthost_str), STRORDASH(ctx->dstport_str),
STRORDASH(ctx->user), ctx->protoctx->is_valid) < 0) { #ifndef WITHOUT_USERAUTH
STRORDASH(ctx->user),
#endif /* !WITHOUT_USERAUTH */
ctx->protoctx->is_valid) < 0) {
break; break;
} }
@ -191,19 +206,35 @@ pxy_thr_print_info(pxy_thr_ctx_t *tctx)
time_t atime = now - ctx->atime; time_t atime = now - ctx->atime;
time_t ctime = now - ctx->ctime; time_t ctime = now - ctx->ctime;
#ifndef WITHOUT_USERAUTH
log_finest_main_va("PARENT CONN: thr=%d, id=%llu, fd=%d, child_fd=%d, dst=%d, srvdst=%d, child_src=%d, child_dst=%d, p=%d-%d-%d c=%d-%d, ce=%d cc=%d, at=%lld ct=%lld, src_addr=%s:%s, dst_addr=%s:%s, user=%s, valid=%d", log_finest_main_va("PARENT CONN: thr=%d, id=%llu, fd=%d, child_fd=%d, dst=%d, srvdst=%d, child_src=%d, child_dst=%d, p=%d-%d-%d c=%d-%d, ce=%d cc=%d, at=%lld ct=%lld, src_addr=%s:%s, dst_addr=%s:%s, user=%s, valid=%d",
tctx->id, ctx->id, ctx->fd, ctx->child_fd, ctx->dst_fd, ctx->srvdst_fd, ctx->child_src_fd, ctx->child_dst_fd, tctx->id, ctx->id, ctx->fd, ctx->child_fd, ctx->dst_fd, ctx->srvdst_fd, ctx->child_src_fd, ctx->child_dst_fd,
ctx->src.closed, ctx->dst.closed, ctx->srvdst.closed, ctx->children ? ctx->children->src.closed : 0, ctx->children ? ctx->children->dst.closed : 0, ctx->src.closed, ctx->dst.closed, ctx->srvdst.closed, ctx->children ? ctx->children->src.closed : 0, ctx->children ? ctx->children->dst.closed : 0,
ctx->children ? 1:0, ctx->child_count, (long long)atime, (long long)ctime, ctx->children ? 1:0, ctx->child_count, (long long)atime, (long long)ctime,
STRORDASH(ctx->srchost_str), STRORDASH(ctx->srcport_str), STRORDASH(ctx->dsthost_str), STRORDASH(ctx->dstport_str), STRORDASH(ctx->srchost_str), STRORDASH(ctx->srcport_str), STRORDASH(ctx->dsthost_str), STRORDASH(ctx->dstport_str),
STRORDASH(ctx->user), ctx->protoctx->is_valid); STRORDASH(ctx->user), ctx->protoctx->is_valid);
#else /* WITHOUT_USERAUTH */
log_finest_main_va("PARENT CONN: thr=%d, id=%llu, fd=%d, child_fd=%d, dst=%d, srvdst=%d, child_src=%d, child_dst=%d, p=%d-%d-%d c=%d-%d, ce=%d cc=%d, at=%lld ct=%lld, src_addr=%s:%s, dst_addr=%s:%s, valid=%d",
tctx->id, ctx->id, ctx->fd, ctx->child_fd, ctx->dst_fd, ctx->srvdst_fd, ctx->child_src_fd, ctx->child_dst_fd,
ctx->src.closed, ctx->dst.closed, ctx->srvdst.closed, ctx->children ? ctx->children->src.closed : 0, ctx->children ? ctx->children->dst.closed : 0,
ctx->children ? 1:0, ctx->child_count, (long long)atime, (long long)ctime,
STRORDASH(ctx->srchost_str), STRORDASH(ctx->srcport_str), STRORDASH(ctx->dsthost_str), STRORDASH(ctx->dstport_str),
ctx->protoctx->is_valid);
#endif /* WITHOUT_USERAUTH */
// @attention Report idle connections only, i.e. the conns which have been idle since the last time we checked for expired conns // @attention Report idle connections only, i.e. the conns which have been idle since the last time we checked for expired conns
if (atime >= (time_t)tctx->thrmgr->global->expired_conn_check_period) { if (atime >= (time_t)tctx->thrmgr->global->expired_conn_check_period) {
if (asprintf(&smsg, "IDLE: atime=%lld, ctime=%lld, src_addr=%s:%s, dst_addr=%s:%s, user=%s, valid=%d\n", if (asprintf(&smsg, "IDLE: atime=%lld, ctime=%lld, src_addr=%s:%s, dst_addr=%s:%s, "
#ifndef WITHOUT_USERAUTH
"user=%s, "
#endif /* !WITHOUT_USERAUTH */
"valid=%d\n",
(long long)atime, (long long)ctime, (long long)atime, (long long)ctime,
STRORDASH(ctx->srchost_str), STRORDASH(ctx->srcport_str), STRORDASH(ctx->dsthost_str), STRORDASH(ctx->dstport_str), STRORDASH(ctx->srchost_str), STRORDASH(ctx->srcport_str), STRORDASH(ctx->dsthost_str), STRORDASH(ctx->dstport_str),
STRORDASH(ctx->user), ctx->protoctx->is_valid) < 0) { #ifndef WITHOUT_USERAUTH
STRORDASH(ctx->user),
#endif /* !WITHOUT_USERAUTH */
ctx->protoctx->is_valid) < 0) {
return; return;
} }
if (log_conn(smsg) == -1) { if (log_conn(smsg) == -1) {

@ -69,8 +69,10 @@ typedef struct pxy_thr_ctx {
// List of active connections on the thread // List of active connections on the thread
pxy_conn_ctx_t *conns; pxy_conn_ctx_t *conns;
#ifndef WITHOUT_USERAUTH
// Per-thread sqlite stmt is necessary to prevent multithreading issues between threads // Per-thread sqlite stmt is necessary to prevent multithreading issues between threads
struct sqlite3_stmt *get_user; struct sqlite3_stmt *get_user;
#endif /* !WITHOUT_USERAUTH */
} pxy_thr_ctx_t; } pxy_thr_ctx_t;
void pxy_thr_attach(pxy_conn_ctx_t *) NONNULL(1); void pxy_thr_attach(pxy_conn_ctx_t *) NONNULL(1);

@ -106,11 +106,13 @@ pxy_thrmgr_run(pxy_thrmgr_ctx_t *ctx)
ctx->thr[i]->timeout_count = 0; ctx->thr[i]->timeout_count = 0;
ctx->thr[i]->thrmgr = ctx; ctx->thr[i]->thrmgr = ctx;
#ifndef WITHOUT_USERAUTH
if ((ctx->global->opts->user_auth || global_has_userauth_spec(ctx->global)) && if ((ctx->global->opts->user_auth || global_has_userauth_spec(ctx->global)) &&
sqlite3_prepare_v2(ctx->global->userdb, "SELECT user,ether,atime,desc FROM users WHERE ip = ?1", 100, &ctx->thr[i]->get_user, NULL)) { sqlite3_prepare_v2(ctx->global->userdb, "SELECT user,ether,atime,desc FROM users WHERE ip = ?1", 100, &ctx->thr[i]->get_user, NULL)) {
log_err_level_printf(LOG_CRIT, "Error preparing get_user sql stmt: %s\n", sqlite3_errmsg(ctx->global->userdb)); log_err_level_printf(LOG_CRIT, "Error preparing get_user sql stmt: %s\n", sqlite3_errmsg(ctx->global->userdb));
goto leave; goto leave;
} }
#endif /* !WITHOUT_USERAUTH */
} }
log_dbg_printf("Initialized %d connection handling threads\n", ctx->num_thr); log_dbg_printf("Initialized %d connection handling threads\n", ctx->num_thr);
@ -144,10 +146,12 @@ leave:
if (ctx->thr[i]->evbase) { if (ctx->thr[i]->evbase) {
event_base_free(ctx->thr[i]->evbase); event_base_free(ctx->thr[i]->evbase);
} }
#ifndef WITHOUT_USERAUTH
if (ctx->global->userdb) { if (ctx->global->userdb) {
// sqlite3.h: "Invoking sqlite3_finalize() on a NULL pointer is a harmless no-op." // sqlite3.h: "Invoking sqlite3_finalize() on a NULL pointer is a harmless no-op."
sqlite3_finalize(ctx->thr[i]->get_user); sqlite3_finalize(ctx->thr[i]->get_user);
} }
#endif /* !WITHOUT_USERAUTH */
free(ctx->thr[i]); free(ctx->thr[i]);
} }
i--; i--;
@ -180,10 +184,12 @@ pxy_thrmgr_free(pxy_thrmgr_ctx_t *ctx)
if (ctx->thr[i]->evbase) { if (ctx->thr[i]->evbase) {
event_base_free(ctx->thr[i]->evbase); event_base_free(ctx->thr[i]->evbase);
} }
#ifndef WITHOUT_USERAUTH
if (ctx->global->userdb) { if (ctx->global->userdb) {
// sqlite3.h: "Invoking sqlite3_finalize() on a NULL pointer is a harmless no-op." // sqlite3.h: "Invoking sqlite3_finalize() on a NULL pointer is a harmless no-op."
sqlite3_finalize(ctx->thr[i]->get_user); sqlite3_finalize(ctx->thr[i]->get_user);
} }
#endif /* !WITHOUT_USERAUTH */
free(ctx->thr[i]); free(ctx->thr[i]);
} }
free(ctx->thr); free(ctx->thr);

@ -619,13 +619,19 @@ START_TEST(opts_set_pass_site_01)
fail_unless(!strcmp(opts->passsites->site, "/example.com/"), "site not /example.com/"); fail_unless(!strcmp(opts->passsites->site, "/example.com/"), "site not /example.com/");
fail_unless(!opts->passsites->ip, "ip set"); fail_unless(!opts->passsites->ip, "ip set");
#ifndef WITHOUT_USERAUTH
fail_unless(!opts->passsites->user, "user set"); fail_unless(!opts->passsites->user, "user set");
fail_unless(!opts->passsites->all, "all not 0"); fail_unless(!opts->passsites->all, "all not 0");
fail_unless(!opts->passsites->keyword, "keyword set"); fail_unless(!opts->passsites->keyword, "keyword set");
#endif /* !WITHOUT_USERAUTH */
fail_unless(!opts->passsites->next, "next set"); fail_unless(!opts->passsites->next, "next set");
ps = passsite_str(opts->passsites); ps = passsite_str(opts->passsites);
#ifndef WITHOUT_USERAUTH
fail_unless(!strcmp(ps, "passsite 0: site=/example.com/,ip=,user=,keyword=,all=0"), "failed parsing passite example.com"); fail_unless(!strcmp(ps, "passsite 0: site=/example.com/,ip=,user=,keyword=,all=0"), "failed parsing passite example.com");
#else /* WITHOUT_USERAUTH */
fail_unless(!strcmp(ps, "passsite 0: site=/example.com/,ip="), "failed parsing passite example.com");
#endif /* WITHOUT_USERAUTH */
free(ps); free(ps);
opts_free(opts); opts_free(opts);
@ -643,19 +649,26 @@ START_TEST(opts_set_pass_site_02)
fail_unless(!strcmp(opts->passsites->site, "/example.com/"), "site not /example.com/"); fail_unless(!strcmp(opts->passsites->site, "/example.com/"), "site not /example.com/");
fail_unless(!strcmp(opts->passsites->ip, "192.168.0.1"), "ip not 192.168.0.1"); fail_unless(!strcmp(opts->passsites->ip, "192.168.0.1"), "ip not 192.168.0.1");
#ifndef WITHOUT_USERAUTH
fail_unless(!opts->passsites->user, "user set"); fail_unless(!opts->passsites->user, "user set");
fail_unless(!opts->passsites->all, "all not 0"); fail_unless(!opts->passsites->all, "all not 0");
fail_unless(!opts->passsites->keyword, "keyword set"); fail_unless(!opts->passsites->keyword, "keyword set");
#endif /* !WITHOUT_USERAUTH */
fail_unless(!opts->passsites->next, "next set"); fail_unless(!opts->passsites->next, "next set");
ps = passsite_str(opts->passsites); ps = passsite_str(opts->passsites);
#ifndef WITHOUT_USERAUTH
fail_unless(!strcmp(ps, "passsite 0: site=/example.com/,ip=192.168.0.1,user=,keyword=,all=0"), "failed parsing passite example.com 192.168.0.1"); fail_unless(!strcmp(ps, "passsite 0: site=/example.com/,ip=192.168.0.1,user=,keyword=,all=0"), "failed parsing passite example.com 192.168.0.1");
#else /* WITHOUT_USERAUTH */
fail_unless(!strcmp(ps, "passsite 0: site=/example.com/,ip=192.168.0.1"), "failed parsing passite example.com 192.168.0.1");
#endif /* !WITHOUT_USERAUTH */
free(ps); free(ps);
opts_free(opts); opts_free(opts);
} }
END_TEST END_TEST
#ifndef WITHOUT_USERAUTH
START_TEST(opts_set_pass_site_03) START_TEST(opts_set_pass_site_03)
{ {
char *ps; char *ps;
@ -705,6 +718,7 @@ START_TEST(opts_set_pass_site_04)
opts_free(opts); opts_free(opts);
} }
END_TEST END_TEST
#endif /* !WITHOUT_USERAUTH */
START_TEST(opts_set_pass_site_05) START_TEST(opts_set_pass_site_05)
{ {
@ -724,6 +738,7 @@ START_TEST(opts_set_pass_site_05)
fail_unless(opts->passsites->next, "next not set"); fail_unless(opts->passsites->next, "next not set");
fail_unless(!opts->passsites->next->next, "next->next set"); fail_unless(!opts->passsites->next->next, "next->next set");
#ifndef WITHOUT_USERAUTH
opts->user_auth = 1; opts->user_auth = 1;
// Use root user, opts_set_pass_site() calls sys_isuser() to validate the user // Use root user, opts_set_pass_site() calls sys_isuser() to validate the user
s = strdup("example.com root"); s = strdup("example.com root");
@ -737,8 +752,10 @@ START_TEST(opts_set_pass_site_05)
s = strdup("*.google.com * android"); s = strdup("*.google.com * android");
opts_set_pass_site(opts, s, 3); opts_set_pass_site(opts, s, 3);
free(s); free(s);
#endif /* !WITHOUT_USERAUTH */
ps = passsite_str(opts->passsites); ps = passsite_str(opts->passsites);
fail_unless(opts->passsites->next, "next not set"); fail_unless(opts->passsites->next, "next not set");
#ifndef WITHOUT_USERAUTH
fail_unless(opts->passsites->next->next, "next->next not set"); fail_unless(opts->passsites->next->next, "next->next not set");
fail_unless(opts->passsites->next->next->next, "next->next->next not set"); fail_unless(opts->passsites->next->next->next, "next->next->next not set");
fail_unless(!opts->passsites->next->next->next->next, "next->next->next->next set"); fail_unless(!opts->passsites->next->next->next->next, "next->next->next->next set");
@ -747,6 +764,11 @@ START_TEST(opts_set_pass_site_05)
"passsite 2: site=/example.com/,ip=192.168.0.1,user=,keyword=,all=0\n" "passsite 2: site=/example.com/,ip=192.168.0.1,user=,keyword=,all=0\n"
"passsite 3: site=/example.com/,ip=,user=,keyword=,all=0"), "passsite 3: site=/example.com/,ip=,user=,keyword=,all=0"),
"failed parsing multiple passites"); "failed parsing multiple passites");
#else /* WITHOUT_USERAUTH */
fail_unless(!strcmp(ps, "passsite 0: site=/example.com/,ip=192.168.0.1\n"
"passsite 1: site=/example.com/,ip="),
"failed parsing multiple passites");
#endif /* WITHOUT_USERAUTH */
free(ps); free(ps);
opts_free(opts); opts_free(opts);
@ -930,8 +952,10 @@ opts_suite(void)
tcase_add_test(tc, opts_debug_01); tcase_add_test(tc, opts_debug_01);
tcase_add_test(tc, opts_set_pass_site_01); tcase_add_test(tc, opts_set_pass_site_01);
tcase_add_test(tc, opts_set_pass_site_02); tcase_add_test(tc, opts_set_pass_site_02);
#ifndef WITHOUT_USERAUTH
tcase_add_test(tc, opts_set_pass_site_03); tcase_add_test(tc, opts_set_pass_site_03);
tcase_add_test(tc, opts_set_pass_site_04); tcase_add_test(tc, opts_set_pass_site_04);
#endif /* !WITHOUT_USERAUTH */
tcase_add_test(tc, opts_set_pass_site_05); tcase_add_test(tc, opts_set_pass_site_05);
tcase_add_test(tc, opts_check_value_yes_01); tcase_add_test(tc, opts_check_value_yes_01);
tcase_add_test(tc, opts_check_value_yes_02); tcase_add_test(tc, opts_check_value_yes_02);

@ -71,7 +71,11 @@ proto_init(protocol_t proto)
spec->smtp = 1; spec->smtp = 1;
} }
pxy_conn_ctx_t *ctx = proxy_conn_ctx_new(0, thrmgr, spec, global, 0); pxy_conn_ctx_t *ctx = proxy_conn_ctx_new(0, thrmgr, spec, global
#ifndef WITHOUT_USERAUTH
, 0
#endif /* !WITHOUT_USERAUTH */
);
pxy_thrmgr_assign_thr(ctx); pxy_thrmgr_assign_thr(ctx);
pxy_thr_attach(ctx); pxy_thr_attach(ctx);

@ -33,7 +33,6 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sqlite3.h>
/* /*
* Print helper for logging code. * Print helper for logging code.

Loading…
Cancel
Save