From 6f5a7ceeb1b76475ac8a9c12aee838b5640a269e Mon Sep 17 00:00:00 2001 From: Soner Tari Date: Tue, 25 Aug 2020 23:32:32 +0300 Subject: [PATCH] Add WITHOUT_USERAUTH switch --- Mk/main.mk | 13 +++++++++ src/main.c | 4 +++ src/opts.c | 57 ++++++++++++++++++++++++++++++++++++--- src/opts.h | 10 +++++++ src/privsep.c | 8 ++++++ src/privsep.h | 2 ++ src/protoautossl.c | 6 +++++ src/protohttp.c | 34 ++++++++++++++++++----- src/protopassthrough.c | 6 +++++ src/protosmtp.c | 2 ++ src/protossl.c | 20 ++++++++++++-- src/prototcp.c | 10 +++++++ src/prototcp.h | 2 ++ src/proxy.c | 23 ++++++++++++---- src/proxy.h | 8 +++++- src/pxyconn.c | 54 +++++++++++++++++++++++++++++-------- src/pxyconn.h | 8 ++++++ src/pxythr.c | 39 ++++++++++++++++++++++++--- src/pxythr.h | 2 ++ src/pxythrmgr.c | 6 +++++ tests/check/opts.t.c | 24 +++++++++++++++++ tests/check/proto.t.c | 6 ++++- tests/testproxy/lp/opts.h | 1 - 23 files changed, 310 insertions(+), 35 deletions(-) diff --git a/Mk/main.mk b/Mk/main.mk index 346386c..024ee3d 100644 --- a/Mk/main.mk +++ b/Mk/main.mk @@ -75,6 +75,13 @@ #FEATURES+= -DWITH_SSLV2 +### User Authentication + +# Define to disable support for user authentication. +# Doing so will remove the dependency on sqlite. +#FEATURES+= -DWITHOUT_USERAUTH + + ### Debugging # These flags are added to CFLAGS iff building from a git repo. @@ -281,10 +288,12 @@ PKGS+= $(shell $(PKGCONFIG) $(PCFLAGS) --exists libpcap \ && echo libpcap) endif endif +ifneq ($(filter -DWITHOUT_USERAUTH,$(FEATURES)),-DWITHOUT_USERAUTH) ifndef SQLITE_BASE PKGS+= $(shell $(PKGCONFIG) $(PCFLAGS) --exists sqlite3 \ && echo sqlite3) endif +endif TPKGS:= ifndef CHECK_BASE TPKGS+= $(shell $(PKGCONFIG) $(PCFLAGS) --exists check \ @@ -328,6 +337,7 @@ $(error dependency 'libpcap' not found; \ endif endif endif +ifneq ($(filter -DWITHOUT_USERAUTH,$(FEATURES)),-DWITHOUT_USERAUTH) ifeq (,$(filter sqlite3,$(PKGS))) SQLITE_FOUND:=$(call locate,sqlite3,include/sqlite3.h,$(SQLITE_BASE)) ifndef SQLITE_FOUND @@ -335,6 +345,7 @@ $(error dependency 'SQLite3' not found; \ install it or point SQLITE_BASE to base path) endif endif +endif ifeq (,$(filter check,$(TPKGS))) CHECK_FOUND:= $(call locate,check,include/check.h,$(CHECK_BASE)) ifndef CHECK_FOUND @@ -385,11 +396,13 @@ PKG_LDFLAGS+= -L$(LIBPCAP_FOUND)/lib PKG_LIBS+= -lpcap endif endif +ifneq ($(filter -DWITHOUT_USERAUTH,$(FEATURES)),-DWITHOUT_USERAUTH) ifdef SQLITE_FOUND PKG_CPPFLAGS+= -I$(SQLITE_FOUND)/include PKG_LDFLAGS+= -L$(SQLITE_FOUND)/lib PKG_LIBS+= -lsqlite3 endif +endif ifdef CHECK_FOUND TPKG_CPPFLAGS+= -I$(CHECK_FOUND)/include TPKG_LDFLAGS+= -L$(CHECK_FOUND)/lib diff --git a/src/main.c b/src/main.c index b53d2e4..d33abb7 100644 --- a/src/main.c +++ b/src/main.c @@ -135,8 +135,10 @@ main_version(void) lpv += 16; fprintf(stderr, "rtlinked against libpcap %s\n", lpv); #endif /* !WITHOUT_MIRROR */ +#ifndef WITHOUT_USERAUTH fprintf(stderr, "compiled against sqlite %s\n", SQLITE_VERSION); fprintf(stderr, "rtlinked against sqlite %s\n", sqlite3_libversion()); +#endif /* !WITHOUT_USERAUTH */ 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->userdb_path) { fprintf(stderr, "User auth requires a userdb path\n"); @@ -660,6 +663,7 @@ main(int argc, char *argv[]) exit(EXIT_FAILURE); } } +#endif /* !WITHOUT_USERAUTH */ /* dynamic defaults */ if (!global->opts->ciphers) { diff --git a/src/opts.c b/src/opts.c index 1eb2df1..bbceb48 100644 --- a/src/opts.c +++ b/src/opts.c @@ -120,7 +120,9 @@ opts_new(void) #endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */ opts->remove_http_referer = 1; opts->verify_peer = 1; +#ifndef WITHOUT_USERAUTH opts->user_timeout = 300; +#endif /* !WITHOUT_USERAUTH */ opts->max_http_header_size = 8192; return opts; } @@ -177,19 +179,23 @@ opts_free(opts_t *opts) if (opts->ciphersuites) { free(opts->ciphersuites); } +#ifndef WITHOUT_USERAUTH if (opts->user_auth_url) { free(opts->user_auth_url); } +#endif /* !WITHOUT_USERAUTH */ passsite_t *passsite = opts->passsites; while (passsite) { passsite_t *next = passsite->next; free(passsite->site); if (passsite->ip) free(passsite->ip); +#ifndef WITHOUT_USERAUTH if (passsite->user) free(passsite->user); if (passsite->keyword) free(passsite->keyword); +#endif /* !WITHOUT_USERAUTH */ free(passsite); passsite = next; } @@ -327,6 +333,7 @@ global_free(global_t *global) free(global->mirrortarget); } #endif /* !WITHOUT_MIRROR */ +#ifndef WITHOUT_USERAUTH if (global->userdb_path) { free(global->userdb_path); } @@ -335,6 +342,7 @@ global_free(global_t *global) sqlite3_finalize(global->update_user_atime); sqlite3_close(global->userdb); } +#endif /* !WITHOUT_USERAUTH */ if (global->opts) { opts_free(global->opts); } @@ -387,6 +395,7 @@ global_has_dns_spec(global_t *global) return 0; } +#ifndef WITHOUT_USERAUTH /* * 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; } +#endif /* !WITHOUT_USERAUTH */ /* * 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; } +#ifndef WITHOUT_USERAUTH static void 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); #endif /* DEBUG_OPTS */ } +#endif /* !WITHOUT_USERAUTH */ static opts_t * 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->verify_peer = global->opts->verify_peer; opts->allow_wrong_host = global->opts->allow_wrong_host; +#ifndef WITHOUT_USERAUTH opts->user_auth = global->opts->user_auth; opts->user_timeout = global->opts->user_timeout; +#endif /* !WITHOUT_USERAUTH */ opts->validate_proto = global->opts->validate_proto; 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) { opts_set_ciphersuites(opts, argv0, global->opts->ciphersuites); } +#ifndef WITHOUT_USERAUTH if (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; 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); if (passsite->ip) ps->ip = strdup(passsite->ip); +#ifndef WITHOUT_USERAUTH if (passsite->user) ps->user = strdup(passsite->user); if (passsite->keyword) ps->keyword = strdup(passsite->keyword); ps->all = passsite->all; +#endif /* !WITHOUT_USERAUTH */ ps->next = opts->passsites; opts->passsites = ps; @@ -941,8 +959,15 @@ passsite_str(passsite_t *passsite) int count = 0; while (passsite) { char *p; - if (asprintf(&p, "site=%s,ip=%s,user=%s,keyword=%s,all=%d", - passsite->site, STRORNONE(passsite->ip), STRORNONE(passsite->user), STRORNONE(passsite->keyword), passsite->all) < 0) { + if (asprintf(&p, "site=%s,ip=%s" +#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; } char *nps; @@ -1009,7 +1034,11 @@ opts_str(opts_t *opts) #ifndef OPENSSL_NO_ECDH "|%s" #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" : ""), #ifdef HAVE_SSLV2 (opts->no_ssl2 ? "|no_ssl2" : ""), @@ -1041,9 +1070,11 @@ opts_str(opts_t *opts) (opts->remove_http_referer ? "|remove_http_referer" : ""), (opts->verify_peer ? "|verify_peer" : ""), (opts->allow_wrong_host ? "|allow_wrong_host" : ""), +#ifndef WITHOUT_USERAUTH (opts->user_auth ? "|user_auth" : ""), (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->max_http_header_size, proto_dump, @@ -1700,6 +1731,7 @@ opts_unset_allow_wrong_host(opts_t *opts) opts->allow_wrong_host = 0; } +#ifndef WITHOUT_USERAUTH static void opts_set_user_auth(UNUSED opts_t *opts) { @@ -1714,6 +1746,7 @@ opts_unset_user_auth(opts_t *opts) { opts->user_auth = 0; } +#endif /* !WITHOUT_USERAUTH */ static void 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); if (argc > 1) { +#ifndef WITHOUT_USERAUTH if (!strcmp(argv[1], "*")) { ps->all = 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]); } else { +#endif /* !WITHOUT_USERAUTH */ ps->ip = strdup(argv[1]); +#ifndef WITHOUT_USERAUTH } +#endif /* !WITHOUT_USERAUTH */ } 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); exit(EXIT_FAILURE); } +#ifndef WITHOUT_USERAUTH ps->keyword = strdup(argv[2]); +#endif /* !WITHOUT_USERAUTH */ } ps->next = opts->passsites; opts->passsites = ps; #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)); +#else /* WITHOUT_USERAUTH */ + log_dbg_printf("PassSite: %s, %s\n", ps->site, STRORDASH(ps->ip)); +#endif /* WITHOUT_USERAUTH */ #endif /* DEBUG_OPTS */ } @@ -2284,6 +2327,7 @@ global_unset_statslog(global_t *global) global->statslog = 0; } +#ifndef WITHOUT_USERAUTH static void 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); #endif /* DEBUG_OPTS */ } +#endif /* !WITHOUT_USERAUTH */ int 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 log_dbg_printf("NATEngine: %s\n", *natengine); #endif /* DEBUG_OPTS */ +#ifndef WITHOUT_USERAUTH } else if (equal(name, "UserAuth")) { yes = check_value_yesno(value, "UserAuth", line_num); if (yes == -1) { @@ -2415,6 +2461,7 @@ set_option(opts_t *opts, const char *argv0, #ifdef DEBUG_OPTS log_dbg_printf("UserTimeout: %u\n", opts->user_timeout); #endif /* DEBUG_OPTS */ +#endif /* !WITHOUT_USERAUTH */ } else if (equal(name, "ValidateProto")) { yes = check_value_yesno(value, "ValidateProto", line_num); if (yes == -1) { @@ -2816,8 +2863,10 @@ set_global_option(global_t *global, const char *argv0, #endif /* DEBUG_OPTS */ } else if (equal(name, "DebugLevel")) { global_set_debug_level(value); +#ifndef WITHOUT_USERAUTH } else if (equal(name, "UserDBPath")) { global_set_userdb_path(global, value); +#endif /* !WITHOUT_USERAUTH */ } else if (equal(name, "ProxySpec")) { if (equal(value, "{")) { #ifdef DEBUG_OPTS diff --git a/src/opts.h b/src/opts.h index 304a122..8649249 100644 --- a/src/opts.h +++ b/src/opts.h @@ -36,9 +36,11 @@ #include "cert.h" #include "attrib.h" +#ifndef WITHOUT_USERAUTH #include #include #include +#endif /* !WITHOUT_USERAUTH */ /* * Print helper for logging code. @@ -94,9 +96,11 @@ typedef struct opts { unsigned int remove_http_referer: 1; unsigned int verify_peer: 1; unsigned int allow_wrong_host: 1; +#ifndef WITHOUT_USERAUTH unsigned int user_auth: 1; char *user_auth_url; unsigned int user_timeout; +#endif /* !WITHOUT_USERAUTH */ unsigned int validate_proto : 1; unsigned int max_http_header_size; struct passsite *passsites; @@ -137,9 +141,11 @@ typedef struct passsite { char *site; // Filter definition fields char *ip; +#ifndef WITHOUT_USERAUTH char *user; unsigned int all : 1; /* 1 for all users */ char *keyword; +#endif /* !WITHOUT_USERAUTH */ struct passsite *next; } passsite_t; @@ -190,9 +196,11 @@ struct global { unsigned int stats_period; unsigned int statslog: 1; unsigned int log_stats: 1; +#ifndef WITHOUT_USERAUTH char *userdb_path; sqlite3 *userdb; struct sqlite3_stmt *update_user_atime; +#endif /* !WITHOUT_USERAUTH */ proxyspec_t *spec; opts_t *opts; @@ -210,11 +218,13 @@ struct global { #endif /* !OPENSSL_NO_ENGINE */ }; +#ifndef WITHOUT_USERAUTH typedef struct userdbkeys { char ip[46]; char user[32]; char ether[18]; } userdbkeys_t; +#endif /* !WITHOUT_USERAUTH */ void NORET oom_die(const char *) NONNULL(1); cert_t *opts_load_cert_chain_key(const char *) NONNULL(1); diff --git a/src/privsep.c b/src/privsep.c index f9bd17e..1e8e2f2 100644 --- a/src/privsep.c +++ b/src/privsep.c @@ -66,7 +66,9 @@ #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_CERTFILE 4 /* open cert file in certgendir */ +#ifndef WITHOUT_USERAUTH #define PRIVSEP_REQ_UPDATE_ATIME 5 /* update ip,user atime */ +#endif /* !WITHOUT_USERAUTH */ /* response byte */ #define PRIVSEP_ANS_SUCCESS 0 /* success */ #define PRIVSEP_ANS_UNK_CMD 1 /* unknown command */ @@ -327,6 +329,7 @@ privsep_server_certfile(const char *fn) return fd; } +#ifndef WITHOUT_USERAUTH static int WUNRES 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); return 0; } +#endif /* !WITHOUT_USERAUTH */ /* * Handle a single request on a readable server socket. @@ -495,6 +499,7 @@ privsep_server_handle_req(global_t *global, int srvsock) /* not reached */ break; } +#ifndef WITHOUT_USERAUTH case PRIVSEP_REQ_UPDATE_ATIME: { userdbkeys_t arg; @@ -531,6 +536,7 @@ privsep_server_handle_req(global_t *global, int srvsock) /* not reached */ break; } +#endif /* !WITHOUT_USERAUTH */ case PRIVSEP_REQ_CERTFILE: { char *fn; int fd; @@ -926,6 +932,7 @@ privsep_client_close(int clisock) return 0; } +#ifndef WITHOUT_USERAUTH int 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 return 0; } +#endif /* !WITHOUT_USERAUTH */ /* * Fork and set up privilege separated monitor process. diff --git a/src/privsep.h b/src/privsep.h index d7e92d5..d3672f9 100644 --- a/src/privsep.h +++ b/src/privsep.h @@ -38,7 +38,9 @@ int privsep_client_openfile(int, const char *, int); int privsep_client_opensock(int, const proxyspec_t *spec); int privsep_client_certfile(int, const char *); int privsep_client_close(int); +#ifndef WITHOUT_USERAUTH int privsep_client_update_atime(int, const userdbkeys_t *); +#endif /* !WITHOUT_USERAUTH */ #endif /* !PRIVSEP_H */ /* vim: set noet ft=c: */ diff --git a/src/protoautossl.c b/src/protoautossl.c index 0bc3a9c..40df672 100644 --- a/src/protoautossl.c +++ b/src/protoautossl.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; +#ifndef WITHOUT_USERAUTH if (prototcp_try_send_userauth_msg(bev, ctx)) { return; } +#endif /* !WITHOUT_USERAUTH */ if (autossl_ctx->clienthello_search) { 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))); +#ifndef WITHOUT_USERAUTH if (prototcp_try_send_userauth_msg(ctx->src.bev, ctx)) { return; } +#endif /* !WITHOUT_USERAUTH */ // @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() @@ -292,9 +296,11 @@ protoautossl_bev_eventcb_connected_srvdst(UNUSED struct bufferevent *bev, pxy_co return; } +#ifndef WITHOUT_USERAUTH if (!ctx->term && !ctx->enomem) { pxy_userauth(ctx); } +#endif /* !WITHOUT_USERAUTH */ } static void NONNULL(1,2) diff --git a/src/protohttp.c b/src/protohttp.c index e5f0d08..d6d0454 100644 --- a/src/protohttp.c +++ b/src/protohttp.c @@ -74,7 +74,11 @@ protohttp_log_connect(pxy_conn_ctx_t *ctx) #ifdef HAVE_LOCAL_PROCINFO " %s" #endif /* HAVE_LOCAL_PROCINFO */ - "%s user:%s\n", + "%s" +#ifndef WITHOUT_USERAUTH + " user:%s" +#endif /* !WITHOUT_USERAUTH */ + "\n", STRORDASH(ctx->srchost_str), STRORDASH(ctx->srcport_str), STRORDASH(ctx->dsthost_str), @@ -87,8 +91,11 @@ protohttp_log_connect(pxy_conn_ctx_t *ctx) #ifdef HAVE_LOCAL_PROCINFO lpi, #endif /* HAVE_LOCAL_PROCINFO */ - http_ctx->ocsp_denied ? " ocsp:denied" : "", - STRORDASH(ctx->user)); + http_ctx->ocsp_denied ? " ocsp:denied" : "" +#ifndef WITHOUT_USERAUTH + , STRORDASH(ctx->user) +#endif /* !WITHOUT_USERAUTH */ + ); } else { rv = asprintf(&msg, "CONN: https %s %s %s %s %s %s %s %s %s " "sni:%s names:%s " @@ -97,7 +104,11 @@ protohttp_log_connect(pxy_conn_ctx_t *ctx) #ifdef HAVE_LOCAL_PROCINFO " %s" #endif /* HAVE_LOCAL_PROCINFO */ - "%s user:%s\n", + "%s" +#ifndef WITHOUT_USERAUTH + " user:%s" +#endif /* !WITHOUT_USERAUTH */ + "\n", STRORDASH(ctx->srchost_str), STRORDASH(ctx->srcport_str), STRORDASH(ctx->dsthost_str), @@ -118,8 +129,11 @@ protohttp_log_connect(pxy_conn_ctx_t *ctx) #ifdef HAVE_LOCAL_PROCINFO lpi, #endif /* HAVE_LOCAL_PROCINFO */ - http_ctx->ocsp_denied ? " ocsp:denied" : "", - STRORDASH(ctx->user)); + http_ctx->ocsp_denied ? " ocsp:denied" : "" +#ifndef WITHOUT_USERAUTH + , STRORDASH(ctx->user) +#endif /* !WITHOUT_USERAUTH */ + ); } if ((rv < 0 ) || !msg) { 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) protohttp_get_url(struct evbuffer *inbuf, pxy_conn_ctx_t *ctx) { @@ -477,6 +492,7 @@ memout: free(path); return url; } +#endif /* !WITHOUT_USERAUTH */ // Size = 39 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) protohttp_bev_readcb_src(struct bufferevent *bev, pxy_conn_ctx_t *ctx) { +#ifndef WITHOUT_USERAUTH static const char redirect[] = "HTTP/1.1 302 Found\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" "Location: %s?SSLproxy=%s\r\n" "\r\n"; +#endif /* !WITHOUT_USERAUTH */ static const char proto_error[] = "HTTP/1.1 400 Bad request\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 *outbuf = bufferevent_get_output(ctx->dst.bev); +#ifndef WITHOUT_USERAUTH if (ctx->spec->opts->user_auth && !ctx->user) { log_finest("Redirecting conn"); 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; return; } +#endif /* !WITHOUT_USERAUTH */ if (ctx->spec->opts->validate_proto && !ctx->protoctx->is_valid) { 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"); +#ifndef WITHOUT_USERAUTH if (prototcp_try_close_unauth_conn(bev, ctx)) { return; } +#endif /* !WITHOUT_USERAUTH */ if (prototcp_try_close_protoerror_conn(bev, ctx)) { return; diff --git a/src/protopassthrough.c b/src/protopassthrough.c index fe664ee..89dbd60 100644 --- a/src/protopassthrough.c +++ b/src/protopassthrough.c @@ -129,9 +129,11 @@ protopassthrough_bev_readcb_src(struct bufferevent *bev, pxy_conn_ctx_t *ctx) return; } +#ifndef WITHOUT_USERAUTH if (prototcp_try_send_userauth_msg(bev, ctx)) { return; } +#endif /* !WITHOUT_USERAUTH */ evbuffer_add_buffer(bufferevent_get_output(ctx->srvdst.bev), bufferevent_get_input(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"); +#ifndef WITHOUT_USERAUTH if (prototcp_try_close_unauth_conn(bev, ctx)) { return; } +#endif /* !WITHOUT_USERAUTH */ // @attention srvdst.bev may be NULL if (ctx->srvdst.closed) { @@ -222,9 +226,11 @@ protopassthrough_bev_eventcb_connected_srvdst(struct bufferevent *bev, pxy_conn_ return; } +#ifndef WITHOUT_USERAUTH if (!ctx->term && !ctx->enomem) { pxy_userauth(ctx); } +#endif /* !WITHOUT_USERAUTH */ } static void NONNULL(1,2) diff --git a/src/protosmtp.c b/src/protosmtp.c index 789917c..c18b4c5 100644 --- a/src/protosmtp.c +++ b/src/protosmtp.c @@ -185,9 +185,11 @@ protosmtp_bev_readcb_srvdst(struct bufferevent *bev, pxy_conn_ctx_t *ctx) return; } +#ifndef WITHOUT_USERAUTH if (prototcp_try_send_userauth_msg(ctx->src.bev, ctx)) { return; } +#endif /* !WITHOUT_USERAUTH */ struct evbuffer *inbuf = bufferevent_get_input(bev); struct evbuffer *outbuf = bufferevent_get_output(ctx->src.bev); diff --git a/src/protossl.c b/src/protossl.c index 37dd7e4..fe7b600 100644 --- a/src/protossl.c +++ b/src/protossl.c @@ -581,10 +581,18 @@ protossl_srccert_create(pxy_conn_ctx_t *ctx) static int NONNULL(1,2) 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)); +#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 - if (!passsite->ip && !passsite->user && !passsite->keyword) { + if (!passsite->ip +#ifndef WITHOUT_USERAUTH + && !passsite->user && !passsite->keyword +#endif /* !WITHOUT_USERAUTH */ + ) { return 1; } @@ -595,14 +603,16 @@ protossl_pass_user(pxy_conn_ctx_t *ctx, passsite_t *passsite) return 1; } +#ifndef WITHOUT_USERAUTH 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 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)))) { return 1; } +#endif /* !WITHOUT_USERAUTH */ return 0; } @@ -720,8 +730,12 @@ protossl_srcssl_create(pxy_conn_ctx_t *ctx, SSL *origssl) while (passsite) { if (protossl_pass_user(ctx, passsite) && protossl_pass_site(ctx, passsite->site)) { // 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, 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); // Differentiate passsite from passthrough option by raising the passsite flag ctx->sslctx->passsite = 1; @@ -1521,9 +1535,11 @@ protossl_bev_eventcb_connected_srvdst(UNUSED struct bufferevent *bev, pxy_conn_c return; } +#ifndef WITHOUT_USERAUTH if (!ctx->term && !ctx->enomem) { pxy_userauth(ctx); } +#endif /* !WITHOUT_USERAUTH */ } static void NONNULL(1,2) diff --git a/src/prototcp.c b/src/prototcp.c index db32c07..1a0a9b9 100644 --- a/src/prototcp.c +++ b/src/prototcp.c @@ -214,6 +214,7 @@ prototcp_init_conn(UNUSED evutil_socket_t fd, UNUSED short what, void *arg) pxy_conn_connect(ctx); } +#ifndef WITHOUT_USERAUTH int 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; } +#endif /* !WITHOUT_USERAUTH */ 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) @@ -266,9 +268,11 @@ prototcp_bev_readcb_src(struct bufferevent *bev, pxy_conn_ctx_t *ctx) return; } +#ifndef WITHOUT_USERAUTH if (prototcp_try_send_userauth_msg(bev, ctx)) { return; } +#endif /* !WITHOUT_USERAUTH */ struct evbuffer *inbuf = bufferevent_get_input(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); } +#ifndef WITHOUT_USERAUTH int 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; } +#endif /* !WITHOUT_USERAUTH */ int 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"); +#ifndef WITHOUT_USERAUTH if (prototcp_try_close_unauth_conn(bev, ctx)) { return; } +#endif /* !WITHOUT_USERAUTH */ if (prototcp_try_close_protoerror_conn(bev, ctx)) { return; @@ -522,9 +530,11 @@ prototcp_bev_eventcb_connected_srvdst(UNUSED struct bufferevent *bev, pxy_conn_c return; } +#ifndef WITHOUT_USERAUTH if (!ctx->term && !ctx->enomem) { pxy_userauth(ctx); } +#endif /* !WITHOUT_USERAUTH */ } void diff --git a/src/prototcp.h b/src/prototcp.h index 9a524b5..138a5dc 100644 --- a/src/prototcp.h +++ b/src/prototcp.h @@ -34,8 +34,10 @@ 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_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); void prototcp_bev_readcb_src(struct bufferevent *, pxy_conn_ctx_t *) NONNULL(1,2); diff --git a/src/proxy.c b/src/proxy.c index 3ef836c..5d7b5ff 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -148,8 +148,11 @@ proxy_setup_proto(pxy_conn_ctx_t *ctx) pxy_conn_ctx_t * proxy_conn_ctx_new(evutil_socket_t fd, pxy_thrmgr_ctx_t *thrmgr, - proxyspec_t *spec, global_t *global, - evutil_socket_t clisock) + proxyspec_t *spec, global_t *global +#ifndef WITHOUT_USERAUTH + , evutil_socket_t clisock +#endif /* !WITHOUT_USERAUTH */ + ) { log_finest_main_va("ENTER, fd=%d", fd); @@ -175,7 +178,9 @@ proxy_conn_ctx_new(evutil_socket_t fd, } ctx->global = global; +#ifndef WITHOUT_USERAUTH ctx->clisock = clisock; +#endif /* !WITHOUT_USERAUTH */ #ifdef HAVE_LOCAL_PROCINFO ctx->lproc.pid = -1; @@ -229,7 +234,11 @@ proxy_listener_acceptcb(UNUSED struct evconnlistener *listener, log_finest_main_va("ENTER, fd=%d", fd); /* 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) { log_err_level_printf(LOG_CRIT, "Error allocating ctx memory\n"); evutil_closesocket(fd); @@ -319,7 +328,9 @@ proxy_listener_setup(struct event_base *evbase, pxy_thrmgr_ctx_t *thrmgr, return NULL; } +#ifndef WITHOUT_USERAUTH lctx->clisock = clisock; +#endif /* !WITHOUT_USERAUTH */ // @attention Do not pass NULL as user-supplied pointer lctx->evcl = evconnlistener_new(evbase, proxy_listener_acceptcb, @@ -490,8 +501,10 @@ proxy_new(global_t *global, int clisock) goto leave4; evtimer_add(ctx->gcev, &gc_delay); - // @attention Do not close privsep sock, we use it to update user atime - //privsep_client_close(clisock); + // @attention Do not close privsep sock if the USERAUTH feature is compiled in, we use it to update user atime +#ifdef WITHOUT_USERAUTH + privsep_client_close(clisock); +#endif /* !WITHOUT_USERAUTH */ return ctx; leave4: diff --git a/src/proxy.h b/src/proxy.h index 9767898..dce9451 100644 --- a/src/proxy.h +++ b/src/proxy.h @@ -44,7 +44,9 @@ typedef struct proxy_listener_ctx { pxy_thrmgr_ctx_t *thrmgr; proxyspec_t *spec; global_t *global; +#ifndef WITHOUT_USERAUTH evutil_socket_t clisock; +#endif /* !WITHOUT_USERAUTH */ struct evconnlistener *evcl; struct proxy_listener_ctx *next; } 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_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 */ /* vim: set noet ft=c: */ diff --git a/src/pxyconn.c b/src/pxyconn.c index 0938ce4..01dd548 100644 --- a/src/pxyconn.c +++ b/src/pxyconn.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) { // 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); @@ -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); } } +#endif /* !WITHOUT_USERAUTH */ pxy_thr_detach(ctx); @@ -368,6 +370,7 @@ pxy_conn_ctx_free(pxy_conn_ctx_t *ctx, int by_requestor) } free(ctx->protoctx); +#ifndef WITHOUT_USERAUTH if (ctx->user) { free(ctx->user); } @@ -377,6 +380,7 @@ pxy_conn_ctx_free(pxy_conn_ctx_t *ctx, int by_requestor) if (ctx->desc) { free(ctx->desc); } +#endif /* !WITHOUT_USERAUTH */ free(ctx); } @@ -454,16 +458,22 @@ pxy_log_connect_nonhttp(pxy_conn_ctx_t *ctx) #ifdef HAVE_LOCAL_PROCINFO " %s" #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")), STRORDASH(ctx->srchost_str), STRORDASH(ctx->srcport_str), STRORDASH(ctx->dsthost_str), - STRORDASH(ctx->dstport_str), + STRORDASH(ctx->dstport_str) #ifdef HAVE_LOCAL_PROCINFO - lpi, + , lpi #endif /* HAVE_LOCAL_PROCINFO */ - STRORDASH(ctx->user)); +#ifndef WITHOUT_USERAUTH + , STRORDASH(ctx->user) +#endif /* !WITHOUT_USERAUTH */ + ); } else { rv = asprintf(&msg, "CONN: %s %s %s %s %s " "sni:%s names:%s " @@ -472,7 +482,10 @@ pxy_log_connect_nonhttp(pxy_conn_ctx_t *ctx) #ifdef HAVE_LOCAL_PROCINFO " %s" #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")), STRORDASH(ctx->srchost_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_cipher), STRORDASH(ctx->sslctx->origcrtfpr), - STRORDASH(ctx->sslctx->usedcrtfpr), + STRORDASH(ctx->sslctx->usedcrtfpr) #ifdef HAVE_LOCAL_PROCINFO - lpi, + , lpi #endif /* HAVE_LOCAL_PROCINFO */ - STRORDASH(ctx->user)); +#ifndef WITHOUT_USERAUTH + , STRORDASH(ctx->user) +#endif /* !WITHOUT_USERAUTH */ + ); } if ((rv < 0) || !msg) { ctx->enomem = 1; @@ -1152,16 +1168,22 @@ pxy_setup_child_listener(pxy_conn_ctx_t *ctx) return -1; } +#ifndef WITHOUT_USERAUTH int user_len = 0; if (ctx->spec->opts->user_auth && ctx->user) { // +1 for comma 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: + + [ + 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 - 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 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)" // 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), - 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() pxy_conn_term(ctx, 1); return -1; @@ -1547,6 +1577,7 @@ pxy_conn_connect(pxy_conn_ctx_t *ctx) } } +#ifndef WITHOUT_USERAUTH #if defined(__OpenBSD__) || defined(__linux__) static void 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; } +#endif /* !WITHOUT_USERAUTH */ int pxy_conn_init(pxy_conn_ctx_t *ctx) diff --git a/src/pxyconn.h b/src/pxyconn.h index 69587ef..dfb5d3c 100644 --- a/src/pxyconn.h +++ b/src/pxyconn.h @@ -52,7 +52,9 @@ #define SSLPROXY_KEY "SSLproxy:" #define SSLPROXY_KEY_LEN strlen(SSLPROXY_KEY) +#ifndef WITHOUT_USERAUTH #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_LEN strlen(PROTOERROR_MSG) @@ -250,8 +252,10 @@ struct pxy_conn_ctx { evutil_socket_t dst_fd; evutil_socket_t srvdst_fd; +#ifndef WITHOUT_USERAUTH // Privsep socket to update user atime evutil_socket_t clisock; +#endif /* !WITHOUT_USERAUTH */ // fd of event listener for children, explicitly closed on error (not for stats only) 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 pxy_conn_ctx_t *next_expired; +#ifndef WITHOUT_USERAUTH // Number of times we try to acquire user db before giving up unsigned int identify_user_count; // User owner of conn @@ -301,6 +306,7 @@ struct pxy_conn_ctx { char *desc; // 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 */ +#endif /* !WITHOUT_USERAUTH */ unsigned int sent_protoerror_msg : 1; /* 1 until error msg is sent */ #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_conn_connect(pxy_conn_ctx_t *) NONNULL(1); +#ifndef WITHOUT_USERAUTH int pxy_userauth(pxy_conn_ctx_t *) NONNULL(1); +#endif /* !WITHOUT_USERAUTH */ void pxy_conn_setup(evutil_socket_t, struct sockaddr *, int, pxy_thrmgr_ctx_t *, proxyspec_t *, global_t *, evutil_socket_t) diff --git a/src/pxythr.c b/src/pxythr.c index 0b4daf5..2f6ab18 100644 --- a/src/pxythr.c +++ b/src/pxythr.c @@ -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 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", 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), 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; - 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, 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; } @@ -191,19 +206,35 @@ pxy_thr_print_info(pxy_thr_ctx_t *tctx) time_t atime = now - ctx->atime; 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", 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), 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 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, 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; } if (log_conn(smsg) == -1) { diff --git a/src/pxythr.h b/src/pxythr.h index dbebd0b..c4b0e89 100644 --- a/src/pxythr.h +++ b/src/pxythr.h @@ -69,8 +69,10 @@ typedef struct pxy_thr_ctx { // List of active connections on the thread pxy_conn_ctx_t *conns; +#ifndef WITHOUT_USERAUTH // Per-thread sqlite stmt is necessary to prevent multithreading issues between threads struct sqlite3_stmt *get_user; +#endif /* !WITHOUT_USERAUTH */ } pxy_thr_ctx_t; void pxy_thr_attach(pxy_conn_ctx_t *) NONNULL(1); diff --git a/src/pxythrmgr.c b/src/pxythrmgr.c index e2a30c1..e15a078 100644 --- a/src/pxythrmgr.c +++ b/src/pxythrmgr.c @@ -106,11 +106,13 @@ pxy_thrmgr_run(pxy_thrmgr_ctx_t *ctx) ctx->thr[i]->timeout_count = 0; ctx->thr[i]->thrmgr = ctx; +#ifndef WITHOUT_USERAUTH 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)) { log_err_level_printf(LOG_CRIT, "Error preparing get_user sql stmt: %s\n", sqlite3_errmsg(ctx->global->userdb)); goto leave; } +#endif /* !WITHOUT_USERAUTH */ } log_dbg_printf("Initialized %d connection handling threads\n", ctx->num_thr); @@ -144,10 +146,12 @@ leave: if (ctx->thr[i]->evbase) { event_base_free(ctx->thr[i]->evbase); } +#ifndef WITHOUT_USERAUTH if (ctx->global->userdb) { // sqlite3.h: "Invoking sqlite3_finalize() on a NULL pointer is a harmless no-op." sqlite3_finalize(ctx->thr[i]->get_user); } +#endif /* !WITHOUT_USERAUTH */ free(ctx->thr[i]); } i--; @@ -180,10 +184,12 @@ pxy_thrmgr_free(pxy_thrmgr_ctx_t *ctx) if (ctx->thr[i]->evbase) { event_base_free(ctx->thr[i]->evbase); } +#ifndef WITHOUT_USERAUTH if (ctx->global->userdb) { // sqlite3.h: "Invoking sqlite3_finalize() on a NULL pointer is a harmless no-op." sqlite3_finalize(ctx->thr[i]->get_user); } +#endif /* !WITHOUT_USERAUTH */ free(ctx->thr[i]); } free(ctx->thr); diff --git a/tests/check/opts.t.c b/tests/check/opts.t.c index e1d4b26..58c416a 100644 --- a/tests/check/opts.t.c +++ b/tests/check/opts.t.c @@ -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(!opts->passsites->ip, "ip set"); +#ifndef WITHOUT_USERAUTH fail_unless(!opts->passsites->user, "user set"); fail_unless(!opts->passsites->all, "all not 0"); fail_unless(!opts->passsites->keyword, "keyword set"); +#endif /* !WITHOUT_USERAUTH */ fail_unless(!opts->passsites->next, "next set"); 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"); +#else /* WITHOUT_USERAUTH */ + fail_unless(!strcmp(ps, "passsite 0: site=/example.com/,ip="), "failed parsing passite example.com"); +#endif /* WITHOUT_USERAUTH */ free(ps); 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->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->all, "all not 0"); fail_unless(!opts->passsites->keyword, "keyword set"); +#endif /* !WITHOUT_USERAUTH */ fail_unless(!opts->passsites->next, "next set"); 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"); +#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); opts_free(opts); } END_TEST +#ifndef WITHOUT_USERAUTH START_TEST(opts_set_pass_site_03) { char *ps; @@ -705,6 +718,7 @@ START_TEST(opts_set_pass_site_04) opts_free(opts); } END_TEST +#endif /* !WITHOUT_USERAUTH */ 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, "next->next set"); +#ifndef WITHOUT_USERAUTH opts->user_auth = 1; // Use root user, opts_set_pass_site() calls sys_isuser() to validate the user s = strdup("example.com root"); @@ -737,8 +752,10 @@ START_TEST(opts_set_pass_site_05) s = strdup("*.google.com * android"); opts_set_pass_site(opts, s, 3); free(s); +#endif /* !WITHOUT_USERAUTH */ ps = passsite_str(opts->passsites); 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->next->next not 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 3: site=/example.com/,ip=,user=,keyword=,all=0"), "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); opts_free(opts); @@ -930,8 +952,10 @@ opts_suite(void) tcase_add_test(tc, opts_debug_01); tcase_add_test(tc, opts_set_pass_site_01); 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_04); +#endif /* !WITHOUT_USERAUTH */ 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_02); diff --git a/tests/check/proto.t.c b/tests/check/proto.t.c index 8518233..79f58ff 100644 --- a/tests/check/proto.t.c +++ b/tests/check/proto.t.c @@ -71,7 +71,11 @@ proto_init(protocol_t proto) 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_thr_attach(ctx); diff --git a/tests/testproxy/lp/opts.h b/tests/testproxy/lp/opts.h index f6f4d70..bbfdd1a 100644 --- a/tests/testproxy/lp/opts.h +++ b/tests/testproxy/lp/opts.h @@ -33,7 +33,6 @@ #include #include -#include /* * Print helper for logging code.