From d67c48a49bb716de0f180fcb98ba6d10727c2355 Mon Sep 17 00:00:00 2001 From: "Daniel M. Drucker" Date: Tue, 18 Jul 2017 17:56:03 -0400 Subject: [PATCH 01/47] tinyproxy configure does not actually support enable-static See #90 and #99 --- README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/README.md b/README.md index 2cb8d59..8b47f0c 100644 --- a/README.md +++ b/README.md @@ -56,9 +56,6 @@ Enable support for proxying connections through another proxy server. - `--enable-transparent`: Allow Tinyproxy to be used as a transparent proxy daemon. -- `--enable-static`: -Compile a static version of Tinyproxy. - - `--enable-reverse`: Enable reverse proxying. From caf0ff3be8d9e6dac936b806e162c02d6c12ec1c Mon Sep 17 00:00:00 2001 From: Steven Conaway Date: Fri, 13 Oct 2017 14:02:49 -0700 Subject: [PATCH 02/47] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8b47f0c..f13e670 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ system. If compiling from a git checkout, you need to first run from the top level directory to generate the `configure` script. The release tarball contains the pre-created `configure` script, -so when building fom a release, you can skip this step. +so when building from a release, you can skip this step. Then basically all you need to do is From 5062b78740285b16a9d37ead23c8d6baa3db8ac4 Mon Sep 17 00:00:00 2001 From: rofl0r Date: Sat, 4 Nov 2017 16:01:59 +0000 Subject: [PATCH 03/47] tinyproxy.conf.in: default to allow CONNECT method more broadly tinyproxy conservatively defaulted to allow CONNECT method only on two ports used by SSL in the ancient past, but since HTTPS usage got much more widespread (actually, it's now the default for the majority of websites), it makes sense now to allow it without restriction by default to accomodate for the new situation. --- etc/tinyproxy.conf.in | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/etc/tinyproxy.conf.in b/etc/tinyproxy.conf.in index e24ad4a..2cde69e 100644 --- a/etc/tinyproxy.conf.in +++ b/etc/tinyproxy.conf.in @@ -283,12 +283,12 @@ ViaProxyName "tinyproxy" # ConnectPort: This is a list of ports allowed by tinyproxy when the # CONNECT method is used. To disable the CONNECT method altogether, set # the value to 0. If no ConnectPort line is found, all ports are -# allowed (which is not very secure.) +# allowed. # # The following two ports are used by SSL. # -ConnectPort 443 -ConnectPort 563 +#ConnectPort 443 +#ConnectPort 563 # # Configure one or more ReversePath directives to enable reverse proxy From d97d486d53ce214ae952378308292f333b8c7a36 Mon Sep 17 00:00:00 2001 From: Pablo Panero Date: Fri, 14 Jul 2017 13:20:21 +0200 Subject: [PATCH 04/47] Issue 15 fix. PR --- src/conf.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/conf.c b/src/conf.c index c003627..d568dfb 100644 --- a/src/conf.c +++ b/src/conf.c @@ -883,10 +883,6 @@ static HANDLE_FUNC (handle_bind) log_message (LOG_INFO, "Outgoing connections bound to IP %s", conf->bind_address); return 0; -#else - fprintf (stderr, - "\"Bind\" cannot be used with transparent support enabled.\n"); - return 1; #endif } From 64b29c5f4e5cf35b9d03fd793e374e27cd83f0b2 Mon Sep 17 00:00:00 2001 From: rofl0r Date: Sat, 4 Nov 2017 19:26:41 +0000 Subject: [PATCH 05/47] do not create a pidfile, if none is specified in config some people want to run tinyproxy with minimal configuration from the command line (and as non-root), but tinyproxy insists on writing a pid file, which only makes sense for usage as a service, hereby forcing the user to either run it as root so it can write to the default location, or start editing the default config file to work around it. and if no pidfile is specified in the config, it frankly doesn't make sense to force creation of one anyway. --- etc/tinyproxy.conf.in | 1 + src/main.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/etc/tinyproxy.conf.in b/etc/tinyproxy.conf.in index 2cde69e..fe0c117 100644 --- a/etc/tinyproxy.conf.in +++ b/etc/tinyproxy.conf.in @@ -121,6 +121,7 @@ LogLevel Info # # PidFile: Write the PID of the main tinyproxy thread to this file so it # can be used for signalling purposes. +# If not specified, no pidfile will be written. # #PidFile "@localstatedir@/run/tinyproxy/tinyproxy.pid" diff --git a/src/main.c b/src/main.c index ae2a3a8..50cacca 100644 --- a/src/main.c +++ b/src/main.c @@ -356,7 +356,7 @@ static void initialize_config_defaults (struct config_s *conf) conf->stathost = safestrdup (TINYPROXY_STATHOST); conf->idletimeout = MAX_IDLE_TIME; conf->logf_name = safestrdup (LOCALSTATEDIR "/log/tinyproxy/tinyproxy.log"); - conf->pidpath = safestrdup (LOCALSTATEDIR "/run/tinyproxy/tinyproxy.pid"); + conf->pidpath = NULL; } /** @@ -496,7 +496,7 @@ main (int argc, char **argv) child_close_sock (); /* Remove the PID file */ - if (unlink (config.pidpath) < 0) { + if (config.pidpath != NULL && unlink (config.pidpath) < 0) { log_message (LOG_WARNING, "Could not remove PID file \"%s\": %s.", config.pidpath, strerror (errno)); From ccbbb81aa99b75ae87c5b245b495700cd8e03124 Mon Sep 17 00:00:00 2001 From: rofl0r Date: Sat, 4 Nov 2017 19:40:42 +0000 Subject: [PATCH 06/47] log to stdout if no logfile specified some users want to run tinyproxy on an as-needed basis in a terminal, without setting it up permanently to run as a daemon/service. in such use case, it is very annoying that tinyproxy didn't have an option to log to stdout, so the user has to keep a second terminal open to `tail -f` the log. additionally, this precluded usage with runit service supervisor, which runs all services in foreground and creates logfiles from the service's stdout/stderr. since logging to stdout doesn't make sense when daemonized, now if no logfile is specified and daemon mode activated, a warning is printed to stderr once, and nothing is logged. the original idea was to fail with an error message, though some users might actually want to run tinyproxy as daemon and no logging at all. --- etc/tinyproxy.conf.in | 3 ++- src/log.c | 14 ++++++++++++-- src/main.c | 9 +++++++-- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/etc/tinyproxy.conf.in b/etc/tinyproxy.conf.in index fe0c117..e1f534a 100644 --- a/etc/tinyproxy.conf.in +++ b/etc/tinyproxy.conf.in @@ -90,7 +90,8 @@ StatFile "@pkgdatadir@/stats.html" # LogFile: Allows you to specify the location where information should # be logged to. If you would prefer to log to syslog, then disable this # and enable the Syslog directive. These directives are mutually -# exclusive. +# exclusive. If neither Syslog nor LogFile are specified, output goes +# to stdout. # #LogFile "@localstatedir@/log/tinyproxy/tinyproxy.log" diff --git a/src/log.c b/src/log.c index f5a0b44..c5368b8 100644 --- a/src/log.c +++ b/src/log.c @@ -70,7 +70,14 @@ static unsigned int logging_initialized = FALSE; /* boolean */ */ int open_log_file (const char *log_file_name) { - log_file_fd = create_file_safely (log_file_name, FALSE); + if (log_file_name == NULL) { + if(config.godaemon == FALSE) + log_file_fd = fileno(stdout); + else + log_file_fd = -1; + } else { + log_file_fd = create_file_safely (log_file_name, FALSE); + } return log_file_fd; } @@ -79,7 +86,7 @@ int open_log_file (const char *log_file_name) */ void close_log_file (void) { - if (log_file_fd < 0) { + if (log_file_fd < 0 || log_file_fd == fileno(stdout)) { return; } @@ -108,6 +115,9 @@ void log_message (int level, const char *fmt, ...) ssize_t ret; + if(!config.syslog && log_file_fd == -1) + return; + #ifdef NDEBUG /* * Figure out if we should write the message or not. diff --git a/src/main.c b/src/main.c index 50cacca..e52b4b2 100644 --- a/src/main.c +++ b/src/main.c @@ -355,7 +355,7 @@ static void initialize_config_defaults (struct config_s *conf) conf->errorpages = NULL; conf->stathost = safestrdup (TINYPROXY_STATHOST); conf->idletimeout = MAX_IDLE_TIME; - conf->logf_name = safestrdup (LOCALSTATEDIR "/log/tinyproxy/tinyproxy.log"); + conf->logf_name = NULL; conf->pidpath = NULL; } @@ -415,8 +415,13 @@ main (int argc, char **argv) anonymous_insert ("Content-Type"); } - if (config.godaemon == TRUE) + if (config.godaemon == TRUE) { + if (!config.syslog && config.logf_name == NULL) + fprintf(stderr, "WARNING: logging deactivated " + "(can't log to stdout when daemonized)\n"); + makedaemon (); + } if (set_signal_handler (SIGPIPE, SIG_IGN) == SIG_ERR) { fprintf (stderr, "%s: Could not set the \"SIGPIPE\" signal.\n", From 08a9fbb0417d168b961aabce51bbbc4218fbf848 Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Wed, 11 Oct 2017 13:24:28 -0700 Subject: [PATCH 07/47] Add example value for Log Level setting --- etc/tinyproxy.conf.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/tinyproxy.conf.in b/etc/tinyproxy.conf.in index e1f534a..4e2ad00 100644 --- a/etc/tinyproxy.conf.in +++ b/etc/tinyproxy.conf.in @@ -103,7 +103,7 @@ StatFile "@pkgdatadir@/stats.html" #Syslog On # -# LogLevel: +# LogLevel: Warning # # Set the logging level. Allowed settings are: # Critical (least verbose) From e9e0f0b4f0341fa279e88d03f0f2baddff43cbe9 Mon Sep 17 00:00:00 2001 From: rofl0r Date: Tue, 28 Nov 2017 21:17:49 +0000 Subject: [PATCH 08/47] configure.ac: remove -Wc++-compat --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 10036ca..3855649 100644 --- a/configure.ac +++ b/configure.ac @@ -173,7 +173,7 @@ AC_CHECK_FUNCS([inet_ntoa strdup]) AC_CHECK_FUNCS([strlcpy strlcat setgroups]) dnl Enable extra warnings -DESIRED_FLAGS="-fdiagnostics-show-option -Wall -Wextra -Wno-unused-parameter -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations -Wfloat-equal -Wundef -Wformat=2 -Wlogical-op -Wmissing-include-dirs -Wformat-nonliteral -Wold-style-definition -Wpointer-arith -Waggregate-return -Winit-self -Wpacked --std=c89 -ansi -pedantic -Wno-overlength-strings -Wc++-compat -Wno-long-long -Wno-overlength-strings -Wdeclaration-after-statement -Wredundant-decls -Wmissing-noreturn -Wshadow -Wendif-labels -Wcast-qual -Wcast-align -Wwrite-strings -Wp,-D_FORTIFY_SOURCE=2 -fno-common" +DESIRED_FLAGS="-fdiagnostics-show-option -Wall -Wextra -Wno-unused-parameter -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations -Wfloat-equal -Wundef -Wformat=2 -Wlogical-op -Wmissing-include-dirs -Wformat-nonliteral -Wold-style-definition -Wpointer-arith -Waggregate-return -Winit-self -Wpacked --std=c89 -ansi -pedantic -Wno-overlength-strings -Wno-long-long -Wno-overlength-strings -Wdeclaration-after-statement -Wredundant-decls -Wmissing-noreturn -Wshadow -Wendif-labels -Wcast-qual -Wcast-align -Wwrite-strings -Wp,-D_FORTIFY_SOURCE=2 -fno-common" if test -n "${MAINTAINER_MODE_FALSE}"; then DESIRED_FLAGS="-Werror $DESIRED_FLAGS" From 9bb699628fe0375ab03fa795c44261e97a898beb Mon Sep 17 00:00:00 2001 From: rofl0r Date: Mon, 4 Dec 2017 11:33:01 +0000 Subject: [PATCH 09/47] safe_write/read: take void* buffer for generic use if using one of unsigned or signed char for the function prototype, one gets nasty warnings when using it with the other type. the only proper solution is to put void* into the prototype, and then specialize the pointer inside the function using an automatic variable. for exactly this reason, libc functions like read(), write(), etc use void* too. --- src/network.c | 5 +++-- src/network.h | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/network.c b/src/network.c index 7bae20b..224f924 100644 --- a/src/network.c +++ b/src/network.c @@ -32,10 +32,11 @@ * Write the buffer to the socket. If an EINTR occurs, pick up and try * again. Keep sending until the buffer has been sent. */ -ssize_t safe_write (int fd, const char *buffer, size_t count) +ssize_t safe_write (int fd, const void *buf, size_t count) { ssize_t len; size_t bytestosend; + const char *buffer = buf; assert (fd >= 0); assert (buffer != NULL); @@ -67,7 +68,7 @@ ssize_t safe_write (int fd, const char *buffer, size_t count) * Matched pair for safe_write(). If an EINTR occurs, pick up and try * again. */ -ssize_t safe_read (int fd, char *buffer, size_t count) +ssize_t safe_read (int fd, void *buffer, size_t count) { ssize_t len; diff --git a/src/network.h b/src/network.h index 15af481..37c0fba 100644 --- a/src/network.h +++ b/src/network.h @@ -21,8 +21,8 @@ #ifndef TINYPROXY_NETWORK_H #define TINYPROXY_NETWORK_H -extern ssize_t safe_write (int fd, const char *buffer, size_t count); -extern ssize_t safe_read (int fd, char *buffer, size_t count); +extern ssize_t safe_write (int fd, const void *buf, size_t count); +extern ssize_t safe_read (int fd, void *buf, size_t count); extern int write_message (int fd, const char *fmt, ...); extern ssize_t readline (int fd, char **whole_buffer); From 116e59e93346ddbe08f56f8c7e8bd648690c0242 Mon Sep 17 00:00:00 2001 From: rofl0r Date: Tue, 9 Jan 2018 20:16:31 +0000 Subject: [PATCH 10/47] activate reverse proxy support by default closes #17 --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 3855649..c3d4ac6 100644 --- a/configure.ac +++ b/configure.ac @@ -113,8 +113,8 @@ dnl Include support for reverse proxy? AH_TEMPLATE([REVERSE_SUPPORT], [Include support for reverse proxy.]) TP_ARG_ENABLE(reverse, - [Enable reverse proxying (default is NO)], - no) + [Enable reverse proxying (default is YES)], + yes) if test x"$reverse_enabled" = x"yes"; then ADDITIONAL_OBJECTS="$ADDITIONAL_OBJECTS reverse-proxy.o" AC_DEFINE(REVERSE_SUPPORT) From 8906b0734e5c61016d9d4090507f010b2006292d Mon Sep 17 00:00:00 2001 From: Gonzalo Tornaria Date: Tue, 20 Dec 2016 21:30:43 +0000 Subject: [PATCH 11/47] add SOCKS upstream proxy support (socks4/socks5) original patch submitted in 2006 to debian mailing list: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=392848%29#12 this version was rebased to git and updated by Russ Dill in 2015 (the original patch used a different config file format). as discussed in #40. commit message by @rofl0r. --- src/conf.c | 34 +++++++++++++++--- src/reqs.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++-- src/upstream.c | 31 ++++++++++++----- src/upstream.h | 5 ++- 4 files changed, 146 insertions(+), 17 deletions(-) diff --git a/src/conf.c b/src/conf.c index d568dfb..ca46930 100644 --- a/src/conf.c +++ b/src/conf.c @@ -160,6 +160,8 @@ static HANDLE_FUNC (handle_xtinyproxy); #ifdef UPSTREAM_SUPPORT static HANDLE_FUNC (handle_upstream); +static HANDLE_FUNC (handle_upstream4); +static HANDLE_FUNC (handle_upstream5); static HANDLE_FUNC (handle_upstream_no); #endif @@ -257,6 +259,14 @@ struct { BEGIN "(upstream)" WS "(" IP "|" ALNUM ")" ":" INT "(" WS STR ")?" END, handle_upstream, NULL }, + { + BEGIN "(upstream4)" WS "(" IP "|" ALNUM ")" ":" INT "(" WS STR + ")?" END, handle_upstream4, NULL + }, + { + BEGIN "(upstream5)" WS "(" IP "|" ALNUM ")" ":" INT "(" WS STR + ")?" END, handle_upstream5, NULL + }, #endif /* loglevel */ STDCONF ("loglevel", "(critical|error|warning|notice|connect|info)", @@ -1066,7 +1076,8 @@ static HANDLE_FUNC (handle_reversepath) #endif #ifdef UPSTREAM_SUPPORT -static HANDLE_FUNC (handle_upstream) +static int _handle_upstream(struct config_s* conf, const char* line, + regmatch_t match[], proxy_type type) { char *ip; int port; @@ -1080,11 +1091,11 @@ static HANDLE_FUNC (handle_upstream) if (match[10].rm_so != -1) { domain = get_string_arg (line, &match[10]); if (domain) { - upstream_add (ip, port, domain, &conf->upstream_list); + upstream_add (ip, port, domain, type, &conf->upstream_list); safefree (domain); } } else { - upstream_add (ip, port, NULL, &conf->upstream_list); + upstream_add (ip, port, NULL, type, &conf->upstream_list); } safefree (ip); @@ -1092,6 +1103,21 @@ static HANDLE_FUNC (handle_upstream) return 0; } +static HANDLE_FUNC (handle_upstream) +{ + return _handle_upstream(conf, line, match, HTTP_TYPE); +} + +static HANDLE_FUNC (handle_upstream4) +{ + return _handle_upstream(conf, line, match, SOCKS4_TYPE); +} + +static HANDLE_FUNC (handle_upstream5) +{ + return _handle_upstream(conf, line, match, SOCKS5_TYPE); +} + static HANDLE_FUNC (handle_upstream_no) { char *domain; @@ -1100,7 +1126,7 @@ static HANDLE_FUNC (handle_upstream_no) if (!domain) return -1; - upstream_add (NULL, 0, domain, &conf->upstream_list); + upstream_add (NULL, 0, domain, HTTP_TYPE, &conf->upstream_list); safefree (domain); return 0; diff --git a/src/reqs.c b/src/reqs.c index 990152a..a3d8162 100644 --- a/src/reqs.c +++ b/src/reqs.c @@ -61,9 +61,11 @@ #ifdef UPSTREAM_SUPPORT # define UPSTREAM_CONFIGURED() (config.upstream_list != NULL) # define UPSTREAM_HOST(host) upstream_get(host, config.upstream_list) +# define UPSTREAM_IS_HTTP(conn) (conn->upstream_proxy != NULL && conn->upstream_proxy->type == HTTP_TYPE) #else # define UPSTREAM_CONFIGURED() (0) # define UPSTREAM_HOST(host) (NULL) +# define UPSTREAM_IS_HTTP(up) (0) #endif /* @@ -853,10 +855,10 @@ process_client_headers (struct conn_s *connptr, hashmap_t hashofheaders) /* * Don't send headers if there's already an error, if the request was * a stats request, or if this was a CONNECT method (unless upstream - * proxy is in use.) + * http proxy is in use.) */ if (connptr->server_fd == -1 || connptr->show_stats - || (connptr->connect_method && (connptr->upstream_proxy == NULL))) { + || (connptr->connect_method && ! UPSTREAM_IS_HTTP(connptr))) { log_message (LOG_INFO, "Not sending client headers to remote machine"); return 0; @@ -1265,6 +1267,88 @@ static void relay_connection (struct conn_s *connptr) return; } +static int +connect_to_upstream_proxy(struct conn_s *connptr, struct request_s *request) +{ + int len; + char buff[512]; /* won't use more than 7 + 255 */ + unsigned short port; + struct hostent *host; + struct upstream *cur_upstream = connptr->upstream_proxy; + + log_message(LOG_CONN, + "Established connection to %s proxy \"%s\" using file descriptor %d.", + proxy_type_name(cur_upstream->type), cur_upstream->host, connptr->server_fd); + + if (cur_upstream->type == SOCKS4_TYPE) { + + buff[0] = 4; /* socks version */ + buff[1] = 1; /* connect command */ + port = htons(request->port); + memcpy(&buff[2], &port, 2); /* dest port */ + host = gethostbyname(request->host); + memcpy(&buff[4], host->h_addr_list[0], 4); /* dest ip */ + buff[8] = 0; /* user */ + if (9 != safe_write(connptr->server_fd, buff, 9)) + return -1; + if (8 != safe_read(connptr->server_fd, buff, 8)) + return -1; + if (buff[0]!=0 || buff[1]!=90) + return -1; + + } else if (cur_upstream->type == SOCKS5_TYPE) { + + /* init */ + buff[0] = 5; /* socks version */ + buff[1] = 1; /* number of methods */ + buff[2] = 0; /* no auth method */ + if (3 != safe_write(connptr->server_fd, buff, 3)) + return -1; + if (2 != safe_read(connptr->server_fd, buff, 2)) + return -1; + if (buff[0]!=5 || buff[1]!=0) + return -1; + /* connect */ + buff[0] = 5; /* socks version */ + buff[1] = 1; /* connect */ + buff[2] = 0; /* reserved */ + buff[3] = 3; /* domainname */ + len=strlen(request->host); + if(len>255) + return -1; + buff[4] = len; /* length of domainname */ + memcpy(&buff[5], request->host, len); /* dest ip */ + port = htons(request->port); + memcpy(&buff[5+len], &port, 2); /* dest port */ + if (7+len != safe_write(connptr->server_fd, buff, 7+len)) + return -1; + if (4 != safe_read(connptr->server_fd, buff, 4)) + return -1; + if (buff[0]!=5 || buff[1]!=0) + return -1; + switch(buff[3]) { + case 1: len=4; break; /* ip v4 */ + case 4: len=16; break; /* ip v6 */ + case 3: /* domainname */ + if (1 != safe_read(connptr->server_fd, buff, 1)) + return -1; + len = buff[0]; /* max = 255 */ + break; + default: return -1; + } + if (2+len != safe_read(connptr->server_fd, buff, 2+len)) + return -1; + } else { + return -1; + } + + if (connptr->connect_method) + return 0; + + return establish_http_connection(connptr, request); +} + + /* * Establish a connection to the upstream proxy server. */ @@ -1308,6 +1392,9 @@ connect_to_upstream (struct conn_s *connptr, struct request_s *request) return -1; } + if (cur_upstream->type != HTTP_TYPE) + return connect_to_upstream_proxy(connptr, request); + log_message (LOG_CONN, "Established connection to upstream proxy \"%s\" " "using file descriptor %d.", @@ -1527,7 +1614,7 @@ void handle_connection (int fd) goto fail; } - if (!(connptr->connect_method && (connptr->upstream_proxy == NULL))) { + if (!connptr->connect_method || UPSTREAM_IS_HTTP(connptr)) { if (process_server_headers (connptr) < 0) { update_stats (STAT_BADCONN); goto fail; diff --git a/src/upstream.c b/src/upstream.c index 6b25f9b..91bf457 100644 --- a/src/upstream.c +++ b/src/upstream.c @@ -29,10 +29,22 @@ #include "log.h" #ifdef UPSTREAM_SUPPORT +const char * +proxy_type_name(proxy_type type) +{ + switch(type) { + case HTTP_TYPE: return "http"; + case SOCKS4_TYPE: return "socks4"; + case SOCKS5_TYPE: return "socks5"; + default: return "unknown"; + } +} + /** * Construct an upstream struct from input data. */ -static struct upstream *upstream_build (const char *host, int port, const char *domain) +static struct upstream *upstream_build (const char *host, int port, const char *domain, + proxy_type type) { char *ptr; struct upstream *up; @@ -44,6 +56,7 @@ static struct upstream *upstream_build (const char *host, int port, const char * return NULL; } + up->type = type; up->host = up->domain = NULL; up->ip = up->mask = 0; @@ -57,8 +70,8 @@ static struct upstream *upstream_build (const char *host, int port, const char * up->host = safestrdup (host); up->port = port; - log_message (LOG_INFO, "Added upstream %s:%d for [default]", - host, port); + log_message (LOG_INFO, "Added upstream %s %s:%d for [default]", + proxy_type_name(type), host, port); } else if (host == NULL) { if (!domain || domain[0] == '\0') { log_message (LOG_WARNING, @@ -101,8 +114,8 @@ static struct upstream *upstream_build (const char *host, int port, const char * up->port = port; up->domain = safestrdup (domain); - log_message (LOG_INFO, "Added upstream %s:%d for %s", - host, port, domain); + log_message (LOG_INFO, "Added upstream %s %s:%d for %s", + proxy_type_name(type), host, port, domain); } return up; @@ -119,11 +132,11 @@ fail: * Add an entry to the upstream list */ void upstream_add (const char *host, int port, const char *domain, - struct upstream **upstream_list) + proxy_type type, struct upstream **upstream_list) { struct upstream *up; - up = upstream_build (host, port, domain); + up = upstream_build (host, port, domain, type); if (up == NULL) { return; } @@ -202,8 +215,8 @@ struct upstream *upstream_get (char *host, struct upstream *up) up = NULL; if (up) - log_message (LOG_INFO, "Found upstream proxy %s:%d for %s", - up->host, up->port, host); + log_message (LOG_INFO, "Found upstream proxy %s %s:%d for %s", + proxy_type_name(up->type), up->host, up->port, host); else log_message (LOG_INFO, "No upstream proxy for %s", host); diff --git a/src/upstream.h b/src/upstream.h index 34dad68..7855214 100644 --- a/src/upstream.h +++ b/src/upstream.h @@ -31,17 +31,20 @@ * Even if upstream support is not compiled into tinyproxy, this * structure still needs to be defined. */ +typedef enum {HTTP_TYPE, SOCKS4_TYPE, SOCKS5_TYPE} proxy_type; struct upstream { struct upstream *next; char *domain; /* optional */ char *host; int port; in_addr_t ip, mask; + proxy_type type; }; #ifdef UPSTREAM_SUPPORT +const char *proxy_type_name(proxy_type type); extern void upstream_add (const char *host, int port, const char *domain, - struct upstream **upstream_list); + proxy_type type, struct upstream **upstream_list); extern struct upstream *upstream_get (char *host, struct upstream *up); extern void free_upstream_list (struct upstream *up); #endif /* UPSTREAM_SUPPORT */ From 7a3fd81a8d3ce30ad8309b5897facde461e1f535 Mon Sep 17 00:00:00 2001 From: rofl0r Date: Mon, 27 Nov 2017 19:12:12 +0000 Subject: [PATCH 12/47] fix types used in SOCKS4/5 support code the line len = buff[0]; /* max = 255 */ could lead to a negative length if the value in buff[0] is > 127. --- src/reqs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/reqs.c b/src/reqs.c index a3d8162..86039bc 100644 --- a/src/reqs.c +++ b/src/reqs.c @@ -1270,8 +1270,8 @@ static void relay_connection (struct conn_s *connptr) static int connect_to_upstream_proxy(struct conn_s *connptr, struct request_s *request) { - int len; - char buff[512]; /* won't use more than 7 + 255 */ + unsigned len; + unsigned char buff[512]; /* won't use more than 7 + 255 */ unsigned short port; struct hostent *host; struct upstream *cur_upstream = connptr->upstream_proxy; From 1ebfd2a2d165bcd9bcebbeb907faf02cb3d54bae Mon Sep 17 00:00:00 2001 From: rofl0r Date: Tue, 26 Dec 2017 17:14:04 +0000 Subject: [PATCH 13/47] tinyproxy.conf.in: add example for SOCKS upstream --- etc/tinyproxy.conf.in | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/etc/tinyproxy.conf.in b/etc/tinyproxy.conf.in index 4e2ad00..bca638a 100644 --- a/etc/tinyproxy.conf.in +++ b/etc/tinyproxy.conf.in @@ -160,6 +160,10 @@ LogLevel Info # # default upstream is internet firewall # upstream firewall.internal.example.com:80 # +# You may also use SOCKS4/SOCKS5 upstream proxies by using upstream4/upstream5: +# upstream4 127.0.0.1:9050 +# upstream5 socksproxy:1080 +# # The LAST matching rule wins the route decision. As you can see, you # can use a host, or a domain: # name matches host exactly From 8db511b9bff5dfa61a9448659e28ce54d9aa8869 Mon Sep 17 00:00:00 2001 From: rofl0r Date: Thu, 16 Nov 2017 12:04:37 +0000 Subject: [PATCH 14/47] add support for basic HTTP authentication using the "BasicAuth" keyword in tinyproxy.conf. base64 code was written by myself and taken from my own library "libulz". for this purpose it is relicensed under the usual terms of the tinyproxy license. --- etc/tinyproxy.conf.in | 5 ++ src/Makefile.am | 1 + src/basicauth.c | 122 ++++++++++++++++++++++++++++++++++++++++++ src/basicauth.h | 31 +++++++++++ src/conf.c | 25 +++++++++ src/conf.h | 1 + src/reqs.c | 25 +++++++++ 7 files changed, 210 insertions(+) create mode 100644 src/basicauth.c create mode 100644 src/basicauth.h diff --git a/etc/tinyproxy.conf.in b/etc/tinyproxy.conf.in index bca638a..c43266b 100644 --- a/etc/tinyproxy.conf.in +++ b/etc/tinyproxy.conf.in @@ -215,6 +215,11 @@ MaxRequestsPerChild 0 # Allow 127.0.0.1 +# BasicAuth: HTTP "Basic Authentication" for accessing the proxy. +# If there are any entries specified, access is only granted for authenticated +# users. +#BasicAuth user password + # # AddHeader: Adds the specified headers to outgoing HTTP requests that # Tinyproxy makes. Note that this option will not work for HTTPS diff --git a/src/Makefile.am b/src/Makefile.am index c42b0dd..60fda2c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -47,6 +47,7 @@ tinyproxy_SOURCES = \ utils.c utils.h \ vector.c vector.h \ upstream.c upstream.h \ + basicauth.c basicauth.h \ connect-ports.c connect-ports.h EXTRA_tinyproxy_SOURCES = filter.c filter.h \ diff --git a/src/basicauth.c b/src/basicauth.c new file mode 100644 index 0000000..ddc6e6e --- /dev/null +++ b/src/basicauth.c @@ -0,0 +1,122 @@ +/* tinyproxy - A fast light-weight HTTP proxy + * This file: Copyright (C) 2016-2017 rofl0r + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "main.h" +#include "basicauth.h" + +#include "conns.h" +#include "heap.h" +#include "html-error.h" +#include "log.h" +#include "conf.h" + +/* calculates number of bytes base64-encoded stream of N bytes will take. */ +#define BASE64ENC_BYTES(N) (((N+2)/3)*4) + +static const char base64_tbl[64] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +/* my own base64 impl (taken from libulz) */ +static void base64enc(char *dst, const void* src, size_t count) +{ + unsigned const char *s = src; + char* d = dst; + while(count) { + int i = 0, n = *s << 16; + s++; + count--; + if(count) { + n |= *s << 8; + s++; + count--; + i++; + } + if(count) { + n |= *s; + s++; + count--; + i++; + } + *d++ = base64_tbl[(n >> 18) & 0x3f]; + *d++ = base64_tbl[(n >> 12) & 0x3f]; + *d++ = i ? base64_tbl[(n >> 6) & 0x3f] : '='; + *d++ = i == 2 ? base64_tbl[n & 0x3f] : '='; + } + *d = 0; +} + +/* + * Add entry to the basicauth list + */ +void basicauth_add (vector_t authlist, + const char *user, const char *pass) +{ + char tmp[256+2]; + char b[BASE64ENC_BYTES((sizeof tmp)-1) + 1]; + int l; + size_t bl; + + if (user == NULL || pass == NULL) { + log_message (LOG_WARNING, + "Illegal basicauth rule: missing user or pass"); + return; + } + + l = snprintf(tmp, sizeof tmp, "%s:%s", user, pass); + + if(l >= (ssize_t) sizeof tmp) { + log_message (LOG_WARNING, + "User / pass in basicauth rule too long"); + return; + } + + base64enc(b, tmp, l); + bl = BASE64ENC_BYTES(l) + 1; + + if (vector_append(authlist, b, bl) == -ENOMEM) { + log_message (LOG_ERR, + "Unable to allocate memory in basicauth_add()"); + return; + } + + log_message (LOG_INFO, + "Added basic auth user : %s", user); +} + +/* + * Check if a user/password combination (encoded as base64) + * is in the basicauth list. + * return 1 on success, 0 on failure. + */ +int basicauth_check (vector_t authlist, const char *authstring) +{ + ssize_t vl, i; + size_t al, el; + const char* entry; + + vl = vector_length (authlist); + if (vl == -EINVAL) return 0; + + al = strlen (authstring); + for (i = 0; i < vl; i++) { + entry = vector_getentry (authlist, i, &el); + if (strncmp (authstring, entry, al) == 0) + return 1; + } + return 0; +} diff --git a/src/basicauth.h b/src/basicauth.h new file mode 100644 index 0000000..e9366bb --- /dev/null +++ b/src/basicauth.h @@ -0,0 +1,31 @@ +/* tinyproxy - A fast light-weight HTTP proxy + * Copyright (C) 2005 Robert James Kaes + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* See 'basicauth.c' for detailed information. */ + +#ifndef TINYPROXY_BASICAUTH_H +#define TINYPROXY_BASICAUTH_H + +#include "vector.h" + +extern void basicauth_add (vector_t authlist, + const char *user, const char *pass); + +extern int basicauth_check (vector_t authlist, const char *authstring); + +#endif diff --git a/src/conf.c b/src/conf.c index ca46930..4ee209d 100644 --- a/src/conf.c +++ b/src/conf.c @@ -36,6 +36,7 @@ #include "reverse-proxy.h" #include "upstream.h" #include "connect-ports.h" +#include "basicauth.h" /* * The configuration directives are defined in the structure below. Each @@ -116,6 +117,7 @@ static HANDLE_FUNC (handle_nop) } /* do nothing function */ static HANDLE_FUNC (handle_allow); +static HANDLE_FUNC (handle_basicauth); static HANDLE_FUNC (handle_anonymous); static HANDLE_FUNC (handle_bind); static HANDLE_FUNC (handle_bindsame); @@ -232,6 +234,7 @@ struct { handle_deny), STDCONF ("bind", "(" IP "|" IPV6 ")", handle_bind), /* other */ + STDCONF ("basicauth", ALNUM WS ALNUM, handle_basicauth), STDCONF ("errorfile", INT WS STR, handle_errorfile), STDCONF ("addheader", STR WS STR, handle_addheader), @@ -299,6 +302,7 @@ static void free_config (struct config_s *conf) safefree (conf->user); safefree (conf->group); vector_delete(conf->listen_addrs); + vector_delete(conf->basicauth_list); #ifdef FILTER_ENABLE safefree (conf->filter); #endif /* FILTER_ENABLE */ @@ -1000,6 +1004,27 @@ static HANDLE_FUNC (handle_loglevel) return -1; } +static HANDLE_FUNC (handle_basicauth) +{ + char *user, *pass; + user = get_string_arg(line, &match[2]); + if (!user) + return -1; + pass = get_string_arg(line, &match[3]); + if (!pass) { + safefree (user); + return -1; + } + if (!conf->basicauth_list) { + conf->basicauth_list = vector_create (); + } + + basicauth_add (conf->basicauth_list, user, pass); + safefree (user); + safefree (pass); + return 0; +} + #ifdef FILTER_ENABLE static HANDLE_FUNC (handle_filter) { diff --git a/src/conf.h b/src/conf.h index 0fb4226..beb2b01 100644 --- a/src/conf.h +++ b/src/conf.h @@ -37,6 +37,7 @@ typedef struct { * Hold all the configuration time information. */ struct config_s { + vector_t basicauth_list; char *logf_name; char *config_file; unsigned int syslog; /* boolean */ diff --git a/src/reqs.c b/src/reqs.c index 86039bc..83fecf3 100644 --- a/src/reqs.c +++ b/src/reqs.c @@ -48,6 +48,7 @@ #include "upstream.h" #include "connect-ports.h" #include "conf.h" +#include "basicauth.h" /* * Maximum length of a HTTP line @@ -1562,6 +1563,30 @@ void handle_connection (int fd) goto fail; } + if (config.basicauth_list != NULL) { + ssize_t len; + char *authstring; + int failure = 1; + len = hashmap_entry_by_key (hashofheaders, "proxy-authorization", + (void **) &authstring); + if (len > 0 && + /* currently only "basic" auth supported */ + (strncmp(authstring, "Basic ", 6) == 0 || + strncmp(authstring, "basic ", 6) == 0) && + basicauth_check (config.basicauth_list, authstring + 6) == 1) + failure = 0; + if(failure) { + update_stats (STAT_DENIED); + indicate_http_error (connptr, 403, "Access denied", + "detail", + "The administrator of this proxy has not configured " + "it to service requests from you.", + NULL); + goto fail; + } + hashmap_remove (hashofheaders, "proxy-authorization"); + } + /* * Add any user-specified headers (AddHeader directive) to the * outgoing HTTP request. From bd04ed00d8b9bac68eaf6f3e7c739ceef043e679 Mon Sep 17 00:00:00 2001 From: rofl0r Date: Sun, 28 Jan 2018 04:32:59 +0000 Subject: [PATCH 15/47] Basic Auth: send correct response codes and headers acc. to rfc7235 as reported by @natedogith1 --- src/html-error.c | 17 ++++++++++++--- src/reqs.c | 54 +++++++++++++++++++++++++++--------------------- 2 files changed, 45 insertions(+), 26 deletions(-) diff --git a/src/html-error.c b/src/html-error.c index 38adf85..0c011a7 100644 --- a/src/html-error.c +++ b/src/html-error.c @@ -156,13 +156,24 @@ send_html_file (FILE *infile, struct conn_s *connptr) int send_http_headers (struct conn_s *connptr, int code, const char *message) { - const char *headers = + const char headers[] = "HTTP/1.0 %d %s\r\n" "Server: %s/%s\r\n" - "Content-Type: text/html\r\n" "Connection: close\r\n" "\r\n"; + "Content-Type: text/html\r\n" + "%s" + "Connection: close\r\n" "\r\n"; + + const char auth_str[] = + "Proxy-Authenticate: Basic realm=\"" + PACKAGE_NAME "\"\r\n"; + + /* according to rfc7235, the 407 error must be accompanied by + a Proxy-Authenticate header field. */ + const char *add = code == 407 ? auth_str : ""; return (write_message (connptr->client_fd, headers, - code, message, PACKAGE, VERSION)); + code, message, PACKAGE, VERSION, + add)); } /* diff --git a/src/reqs.c b/src/reqs.c index 83fecf3..0e4e5f7 100644 --- a/src/reqs.c +++ b/src/reqs.c @@ -1563,29 +1563,37 @@ void handle_connection (int fd) goto fail; } - if (config.basicauth_list != NULL) { - ssize_t len; - char *authstring; - int failure = 1; - len = hashmap_entry_by_key (hashofheaders, "proxy-authorization", - (void **) &authstring); - if (len > 0 && - /* currently only "basic" auth supported */ - (strncmp(authstring, "Basic ", 6) == 0 || - strncmp(authstring, "basic ", 6) == 0) && - basicauth_check (config.basicauth_list, authstring + 6) == 1) - failure = 0; - if(failure) { - update_stats (STAT_DENIED); - indicate_http_error (connptr, 403, "Access denied", - "detail", - "The administrator of this proxy has not configured " - "it to service requests from you.", - NULL); - goto fail; - } - hashmap_remove (hashofheaders, "proxy-authorization"); - } + if (config.basicauth_list != NULL) { + ssize_t len; + char *authstring; + int failure = 1; + len = hashmap_entry_by_key (hashofheaders, "proxy-authorization", + (void **) &authstring); + + if (len == 0) { + update_stats (STAT_DENIED); + indicate_http_error (connptr, 407, "Proxy Authentication Required", + "detail", + "This proxy requires authentication.", + NULL); + goto fail; + } + if ( /* currently only "basic" auth supported */ + (strncmp(authstring, "Basic ", 6) == 0 || + strncmp(authstring, "basic ", 6) == 0) && + basicauth_check (config.basicauth_list, authstring + 6) == 1) + failure = 0; + if(failure) { + update_stats (STAT_DENIED); + indicate_http_error (connptr, 401, "Unauthorized", + "detail", + "The administrator of this proxy has not configured " + "it to service requests from you.", + NULL); + goto fail; + } + hashmap_remove (hashofheaders, "proxy-authorization"); + } /* * Add any user-specified headers (AddHeader directive) to the From af1d7ab510f8dc9954c8a1d47149c92c2a2c15fa Mon Sep 17 00:00:00 2001 From: rofl0r Date: Tue, 6 Feb 2018 16:50:00 +0000 Subject: [PATCH 16/47] move base64 code into own file it will be needed to add support for upstream proxy auth. --- src/Makefile.am | 1 + src/base64.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++ src/base64.h | 29 +++++++++++++++++++++++++ src/basicauth.c | 36 +------------------------------ 4 files changed, 88 insertions(+), 35 deletions(-) create mode 100644 src/base64.c create mode 100644 src/base64.h diff --git a/src/Makefile.am b/src/Makefile.am index 60fda2c..565eb4d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -48,6 +48,7 @@ tinyproxy_SOURCES = \ vector.c vector.h \ upstream.c upstream.h \ basicauth.c basicauth.h \ + base64.c base64.h \ connect-ports.c connect-ports.h EXTRA_tinyproxy_SOURCES = filter.c filter.h \ diff --git a/src/base64.c b/src/base64.c new file mode 100644 index 0000000..cc9b6ae --- /dev/null +++ b/src/base64.c @@ -0,0 +1,57 @@ +/* tinyproxy - A fast light-weight HTTP proxy + * this file Copyright (C) 2016-2018 rofl0r + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "base64.h" + +static const char base64_tbl[64] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +/* + rofl0r's base64 impl (taken from libulz) + takes count bytes from src, writing base64 encoded string into dst. + dst needs to be at least BASE64ENC_BYTES(count) + 1 bytes in size. + the string in dst will be zero-terminated. + */ +void base64enc(char *dst, const void* src, size_t count) +{ + unsigned const char *s = src; + char* d = dst; + while(count) { + int i = 0, n = *s << 16; + s++; + count--; + if(count) { + n |= *s << 8; + s++; + count--; + i++; + } + if(count) { + n |= *s; + s++; + count--; + i++; + } + *d++ = base64_tbl[(n >> 18) & 0x3f]; + *d++ = base64_tbl[(n >> 12) & 0x3f]; + *d++ = i ? base64_tbl[(n >> 6) & 0x3f] : '='; + *d++ = i == 2 ? base64_tbl[n & 0x3f] : '='; + } + *d = 0; +} + diff --git a/src/base64.h b/src/base64.h new file mode 100644 index 0000000..4465b9e --- /dev/null +++ b/src/base64.h @@ -0,0 +1,29 @@ +/* tinyproxy - A fast light-weight HTTP proxy + * this file Copyright (C) 2016-2018 rofl0r + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef TINYPROXY_BASE64_H +#define TINYPROXY_BASE64_H + +#include + +/* calculates number of bytes base64-encoded stream of N bytes will take. */ +#define BASE64ENC_BYTES(N) (((N+2)/3)*4) +void base64enc(char *dst, const void* src, size_t count); + +#endif + diff --git a/src/basicauth.c b/src/basicauth.c index ddc6e6e..4360a1a 100644 --- a/src/basicauth.c +++ b/src/basicauth.c @@ -24,41 +24,7 @@ #include "html-error.h" #include "log.h" #include "conf.h" - -/* calculates number of bytes base64-encoded stream of N bytes will take. */ -#define BASE64ENC_BYTES(N) (((N+2)/3)*4) - -static const char base64_tbl[64] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -/* my own base64 impl (taken from libulz) */ -static void base64enc(char *dst, const void* src, size_t count) -{ - unsigned const char *s = src; - char* d = dst; - while(count) { - int i = 0, n = *s << 16; - s++; - count--; - if(count) { - n |= *s << 8; - s++; - count--; - i++; - } - if(count) { - n |= *s; - s++; - count--; - i++; - } - *d++ = base64_tbl[(n >> 18) & 0x3f]; - *d++ = base64_tbl[(n >> 12) & 0x3f]; - *d++ = i ? base64_tbl[(n >> 6) & 0x3f] : '='; - *d++ = i == 2 ? base64_tbl[n & 0x3f] : '='; - } - *d = 0; -} +#include "base64.h" /* * Add entry to the basicauth list From 9acb0cb16cb65a554c5443f0409f827390379249 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 16 Nov 2017 01:52:55 +0100 Subject: [PATCH 17/47] Fix CVE-2017-11747: Create PID file before dropping privileges. Resolves #106 Signed-off-by: Michael Adam --- src/main.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main.c b/src/main.c index e52b4b2..35ff704 100644 --- a/src/main.c +++ b/src/main.c @@ -441,6 +441,15 @@ main (int argc, char **argv) exit (EX_OSERR); } + /* Create pid file before we drop privileges */ + if (config.pidpath) { + if (pidfile_create (config.pidpath) < 0) { + fprintf (stderr, "%s: Could not create PID file.\n", + argv[0]); + exit (EX_OSERR); + } + } + /* Switch to a different user if we're running as root */ if (geteuid () == 0) change_user (argv[0]); @@ -453,15 +462,6 @@ main (int argc, char **argv) exit (EX_SOFTWARE); } - /* Create pid file after we drop privileges */ - if (config.pidpath) { - if (pidfile_create (config.pidpath) < 0) { - fprintf (stderr, "%s: Could not create PID file.\n", - argv[0]); - exit (EX_OSERR); - } - } - if (child_pool_create () < 0) { fprintf (stderr, "%s: Could not create the pool of children.\n", From c7c88e9c59a15d23a3de7d2e22781c57ec49b1fe Mon Sep 17 00:00:00 2001 From: John Weldon Date: Tue, 20 Feb 2018 09:29:11 -0700 Subject: [PATCH 18/47] Remove #ifdef for HAVE_SYSLOG_H - syslog.h is a standard posix header, this #ifdef is an artifact accidentally left in. --- src/conf.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/conf.c b/src/conf.c index 4ee209d..80bdab8 100644 --- a/src/conf.c +++ b/src/conf.c @@ -783,12 +783,7 @@ static HANDLE_FUNC (handle_xtinyproxy) static HANDLE_FUNC (handle_syslog) { -#ifdef HAVE_SYSLOG_H return set_bool_arg (&conf->syslog, line, &match[2]); -#else - fprintf (stderr, "Syslog support not compiled in executable.\n"); - return 1; -#endif } static HANDLE_FUNC (handle_bindsame) From 81ea4feb2ed6ee2fabd4e2ec0557318d764757a2 Mon Sep 17 00:00:00 2001 From: bertliao Date: Sun, 25 Feb 2018 12:18:46 +0800 Subject: [PATCH 19/47] fix possible memory leak --- src/transparent-proxy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/transparent-proxy.c b/src/transparent-proxy.c index 5d0c8f6..df5fbce 100644 --- a/src/transparent-proxy.c +++ b/src/transparent-proxy.c @@ -45,7 +45,7 @@ static int build_url (char **url, const char *host, int port, const char *path) assert (path != NULL); len = strlen (host) + strlen (path) + 14; - *url = (char *) safemalloc (len); + *url = (char *) saferealloc (*url, len); if (*url == NULL) return -1; From 4d9891e59e7c7ee77137fcdb3d02798af96811ff Mon Sep 17 00:00:00 2001 From: rofl0r Date: Fri, 23 Feb 2018 20:16:39 +0000 Subject: [PATCH 20/47] basicauth.[ch]: refactor to make basicauth_string() reusable --- src/basicauth.c | 41 ++++++++++++++++++++++++++--------------- src/basicauth.h | 4 ++++ 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/src/basicauth.c b/src/basicauth.c index 4360a1a..7092657 100644 --- a/src/basicauth.c +++ b/src/basicauth.c @@ -26,35 +26,46 @@ #include "conf.h" #include "base64.h" +/* + * Create basic-auth token in buf. + * Returns strlen of token on success, + * -1 if user/pass missing + * 0 if user/pass too long + */ +ssize_t basicauth_string(const char *user, const char *pass, + char *buf, size_t bufsize) +{ + char tmp[256+2]; + int l; + if (!user || !pass) return -1; + l = snprintf(tmp, sizeof tmp, "%s:%s", user, pass); + if (l < 0 || l >= (ssize_t) sizeof tmp) return 0; + if (bufsize < (BASE64ENC_BYTES((unsigned)l) + 1)) return 0; + base64enc(buf, tmp, l); + return BASE64ENC_BYTES(l); +} + /* * Add entry to the basicauth list */ void basicauth_add (vector_t authlist, const char *user, const char *pass) { - char tmp[256+2]; - char b[BASE64ENC_BYTES((sizeof tmp)-1) + 1]; - int l; - size_t bl; + char b[BASE64ENC_BYTES((256+2)-1) + 1]; + ssize_t ret; - if (user == NULL || pass == NULL) { + ret = basicauth_string(user, pass, b, sizeof b); + if (ret == -1) { log_message (LOG_WARNING, "Illegal basicauth rule: missing user or pass"); return; - } - - l = snprintf(tmp, sizeof tmp, "%s:%s", user, pass); - - if(l >= (ssize_t) sizeof tmp) { + } else if (ret == 0) { log_message (LOG_WARNING, - "User / pass in basicauth rule too long"); + "User / pass in basicauth rule too long"); return; } - base64enc(b, tmp, l); - bl = BASE64ENC_BYTES(l) + 1; - - if (vector_append(authlist, b, bl) == -ENOMEM) { + if (vector_append(authlist, b, ret + 1) == -ENOMEM) { log_message (LOG_ERR, "Unable to allocate memory in basicauth_add()"); return; diff --git a/src/basicauth.h b/src/basicauth.h index e9366bb..61dc5c3 100644 --- a/src/basicauth.h +++ b/src/basicauth.h @@ -21,8 +21,12 @@ #ifndef TINYPROXY_BASICAUTH_H #define TINYPROXY_BASICAUTH_H +#include #include "vector.h" +extern ssize_t basicauth_string(const char *user, const char *pass, + char *buf, size_t bufsize); + extern void basicauth_add (vector_t authlist, const char *user, const char *pass); From bf76aeeba1cf868ebe4d2f28976abb75c48031b0 Mon Sep 17 00:00:00 2001 From: rofl0r Date: Fri, 23 Feb 2018 20:21:32 +0000 Subject: [PATCH 21/47] implement HTTP basic auth for upstream proxies loosely based on @valenbg1's code from PR #38 closes #38 closes #96 --- etc/tinyproxy.conf.in | 3 +++ src/conf.c | 44 +++++++++++++++++++++++++++---------------- src/reqs.c | 11 +++++++++++ src/upstream.c | 26 +++++++++++++++++++++++-- src/upstream.h | 6 ++++++ 5 files changed, 72 insertions(+), 18 deletions(-) diff --git a/etc/tinyproxy.conf.in b/etc/tinyproxy.conf.in index c43266b..ac16efe 100644 --- a/etc/tinyproxy.conf.in +++ b/etc/tinyproxy.conf.in @@ -146,6 +146,9 @@ LogLevel Info # upstream testproxy:8008 ".our_testbed.example.com" # upstream testproxy:8008 "192.168.128.0/255.255.254.0" # +# # upstream proxy using basic authentication +# upstream user:pass@testproxy:8008 ".test.domain.invalid" +# # # no upstream proxy for internal websites and unqualified hosts # no upstream ".internal.example.com" # no upstream "www.example.com" diff --git a/src/conf.c b/src/conf.c index 80bdab8..7f62172 100644 --- a/src/conf.c +++ b/src/conf.c @@ -259,8 +259,11 @@ struct { BEGIN "(no" WS "upstream)" WS STR END, handle_upstream_no, NULL }, { - BEGIN "(upstream)" WS "(" IP "|" ALNUM ")" ":" INT "(" WS STR - ")?" END, handle_upstream, NULL + BEGIN "(upstream)" WS + "(" ALNUM /*username*/ ":" ALNUM /*password*/ "@" ")?" + "(" IP "|" ALNUM ")" + ":" INT "(" WS STR ")?" + END, handle_upstream, NULL }, { BEGIN "(upstream4)" WS "(" IP "|" ALNUM ")" ":" INT "(" WS STR @@ -1100,24 +1103,33 @@ static int _handle_upstream(struct config_s* conf, const char* line, regmatch_t match[], proxy_type type) { char *ip; - int port; - char *domain; + int port, mi = 3; + char *domain = 0, *user = 0, *pass = 0; - ip = get_string_arg (line, &match[2]); + if (match[mi].rm_so != -1) + user = get_string_arg (line, &match[mi]); + mi++; + + if (match[mi].rm_so != -1) + pass = get_string_arg (line, &match[mi]); + mi++; + + ip = get_string_arg (line, &match[mi]); if (!ip) return -1; - port = (int) get_long_arg (line, &match[7]); + mi += 5; - if (match[10].rm_so != -1) { - domain = get_string_arg (line, &match[10]); - if (domain) { - upstream_add (ip, port, domain, type, &conf->upstream_list); - safefree (domain); - } - } else { - upstream_add (ip, port, NULL, type, &conf->upstream_list); - } + port = (int) get_long_arg (line, &match[mi]); + mi += 3; + if (match[mi].rm_so != -1) + domain = get_string_arg (line, &match[mi]); + + upstream_add (ip, port, domain, user, pass, type, &conf->upstream_list); + + safefree (user); + safefree (pass); + safefree (domain); safefree (ip); return 0; @@ -1146,7 +1158,7 @@ static HANDLE_FUNC (handle_upstream_no) if (!domain) return -1; - upstream_add (NULL, 0, domain, HTTP_TYPE, &conf->upstream_list); + upstream_add (NULL, 0, domain, 0, 0, HTTP_TYPE, &conf->upstream_list); safefree (domain); return 0; diff --git a/src/reqs.c b/src/reqs.c index 0e4e5f7..180b35a 100644 --- a/src/reqs.c +++ b/src/reqs.c @@ -270,6 +270,17 @@ establish_http_connection (struct conn_s *connptr, struct request_s *request) "Connection: close\r\n", request->method, request->path, request->host, portbuff); + } else if (connptr->upstream_proxy && + connptr->upstream_proxy->type == HTTP_TYPE && + connptr->upstream_proxy->ua.authstr) { + return write_message (connptr->server_fd, + "%s %s HTTP/1.0\r\n" + "Host: %s%s\r\n" + "Connection: close\r\n" + "Proxy-Authorization: Basic %s\r\n", + request->method, request->path, + request->host, portbuff, + connptr->upstream_proxy->ua.authstr); } else { return write_message (connptr->server_fd, "%s %s HTTP/1.0\r\n" diff --git a/src/upstream.c b/src/upstream.c index 91bf457..03a6b8e 100644 --- a/src/upstream.c +++ b/src/upstream.c @@ -27,6 +27,8 @@ #include "upstream.h" #include "heap.h" #include "log.h" +#include "base64.h" +#include "basicauth.h" #ifdef UPSTREAM_SUPPORT const char * @@ -44,6 +46,7 @@ proxy_type_name(proxy_type type) * Construct an upstream struct from input data. */ static struct upstream *upstream_build (const char *host, int port, const char *domain, + const char *user, const char *pass, proxy_type type) { char *ptr; @@ -57,8 +60,24 @@ static struct upstream *upstream_build (const char *host, int port, const char * } up->type = type; - up->host = up->domain = NULL; + up->host = up->domain = up->ua.user = up->pass = NULL; up->ip = up->mask = 0; + if (user) { + if (type == HTTP_TYPE) { + char b[BASE64ENC_BYTES((256+2)-1) + 1]; + ssize_t ret; + ret = basicauth_string(user, pass, b, sizeof b); + if (ret == 0) { + log_message (LOG_ERR, + "User / pass in upstream config too long"); + return NULL; + } + up->ua.authstr = safestrdup (b); + } else { + up->ua.user = safestrdup (user); + up->pass = safestrdup (pass); + } + } if (domain == NULL) { if (!host || host[0] == '\0' || port < 1) { @@ -121,6 +140,8 @@ static struct upstream *upstream_build (const char *host, int port, const char * return up; fail: + safefree (up->ua.user); + safefree (up->pass); safefree (up->host); safefree (up->domain); safefree (up); @@ -132,11 +153,12 @@ fail: * Add an entry to the upstream list */ void upstream_add (const char *host, int port, const char *domain, + const char *user, const char *pass, proxy_type type, struct upstream **upstream_list) { struct upstream *up; - up = upstream_build (host, port, domain, type); + up = upstream_build (host, port, domain, user, pass, type); if (up == NULL) { return; } diff --git a/src/upstream.h b/src/upstream.h index 7855214..9b664c8 100644 --- a/src/upstream.h +++ b/src/upstream.h @@ -36,6 +36,11 @@ struct upstream { struct upstream *next; char *domain; /* optional */ char *host; + union { + char *user; + char *authstr; + } ua; + char *pass; int port; in_addr_t ip, mask; proxy_type type; @@ -44,6 +49,7 @@ struct upstream { #ifdef UPSTREAM_SUPPORT const char *proxy_type_name(proxy_type type); extern void upstream_add (const char *host, int port, const char *domain, + const char *user, const char *pass, proxy_type type, struct upstream **upstream_list); extern struct upstream *upstream_get (char *host, struct upstream *up); extern void free_upstream_list (struct upstream *up); From e1c11c47db91597f0041152fc06e7b558cdfc9e1 Mon Sep 17 00:00:00 2001 From: rofl0r Date: Sun, 25 Feb 2018 17:59:16 +0000 Subject: [PATCH 22/47] make send_stored_logs static --- src/log.c | 2 +- src/log.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/log.c b/src/log.c index c5368b8..69b6dc0 100644 --- a/src/log.c +++ b/src/log.c @@ -217,7 +217,7 @@ out: /* * This needs to send any stored log messages. */ -void send_stored_logs (void) +static void send_stored_logs (void) { char *string; char *ptr; diff --git a/src/log.h b/src/log.h index 68c89c3..76bfe6b 100644 --- a/src/log.h +++ b/src/log.h @@ -106,7 +106,6 @@ extern void close_log_file (void); extern void log_message (int level, const char *fmt, ...); extern void set_log_level (int level); -extern void send_stored_logs (void); extern int setup_logging (void); extern void shutdown_logging (void); From 86632a91eb65d6b3df7bcdaebef3e1ea4e3a568a Mon Sep 17 00:00:00 2001 From: rofl0r Date: Sun, 25 Feb 2018 17:59:24 +0000 Subject: [PATCH 23/47] fix early logging tinyproxy uses a curious mechanism to log those early messages that result from parsing the config file before the logging mechanism has been properly set up yet by finishing parsing of the config file: those early messages are written into a memory buffer and then are printed later on. this slipped my attention when making it possible to log to stdout in ccbbb81a. --- src/log.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/log.c b/src/log.c index 69b6dc0..f85d29d 100644 --- a/src/log.c +++ b/src/log.c @@ -115,9 +115,6 @@ void log_message (int level, const char *fmt, ...) ssize_t ret; - if(!config.syslog && log_file_fd == -1) - return; - #ifdef NDEBUG /* * Figure out if we should write the message or not. @@ -164,6 +161,9 @@ void log_message (int level, const char *fmt, ...) goto out; } + if(!config.syslog && log_file_fd == -1) + goto out; + if (config.syslog) { #ifdef HAVE_VSYSLOG_H vsyslog (level, fmt, args); From 39132b978707fc284199b2b947af6c8c846cade8 Mon Sep 17 00:00:00 2001 From: rofl0r Date: Sun, 25 Feb 2018 15:53:43 +0000 Subject: [PATCH 24/47] rename members of proxy_type enum to have a common prefix and add a NONE member. --- src/conf.c | 8 ++++---- src/reqs.c | 10 +++++----- src/upstream.c | 9 +++++---- src/upstream.h | 8 +++++++- 4 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/conf.c b/src/conf.c index 7f62172..ca9764e 100644 --- a/src/conf.c +++ b/src/conf.c @@ -1137,17 +1137,17 @@ static int _handle_upstream(struct config_s* conf, const char* line, static HANDLE_FUNC (handle_upstream) { - return _handle_upstream(conf, line, match, HTTP_TYPE); + return _handle_upstream(conf, line, match, PT_HTTP); } static HANDLE_FUNC (handle_upstream4) { - return _handle_upstream(conf, line, match, SOCKS4_TYPE); + return _handle_upstream(conf, line, match, PT_SOCKS4); } static HANDLE_FUNC (handle_upstream5) { - return _handle_upstream(conf, line, match, SOCKS5_TYPE); + return _handle_upstream(conf, line, match, PT_SOCKS5); } static HANDLE_FUNC (handle_upstream_no) @@ -1158,7 +1158,7 @@ static HANDLE_FUNC (handle_upstream_no) if (!domain) return -1; - upstream_add (NULL, 0, domain, 0, 0, HTTP_TYPE, &conf->upstream_list); + upstream_add (NULL, 0, domain, 0, 0, PT_HTTP, &conf->upstream_list); safefree (domain); return 0; diff --git a/src/reqs.c b/src/reqs.c index 180b35a..a71cd47 100644 --- a/src/reqs.c +++ b/src/reqs.c @@ -62,7 +62,7 @@ #ifdef UPSTREAM_SUPPORT # define UPSTREAM_CONFIGURED() (config.upstream_list != NULL) # define UPSTREAM_HOST(host) upstream_get(host, config.upstream_list) -# define UPSTREAM_IS_HTTP(conn) (conn->upstream_proxy != NULL && conn->upstream_proxy->type == HTTP_TYPE) +# define UPSTREAM_IS_HTTP(conn) (conn->upstream_proxy != NULL && conn->upstream_proxy->type == PT_HTTP) #else # define UPSTREAM_CONFIGURED() (0) # define UPSTREAM_HOST(host) (NULL) @@ -271,7 +271,7 @@ establish_http_connection (struct conn_s *connptr, struct request_s *request) request->method, request->path, request->host, portbuff); } else if (connptr->upstream_proxy && - connptr->upstream_proxy->type == HTTP_TYPE && + connptr->upstream_proxy->type == PT_HTTP && connptr->upstream_proxy->ua.authstr) { return write_message (connptr->server_fd, "%s %s HTTP/1.0\r\n" @@ -1292,7 +1292,7 @@ connect_to_upstream_proxy(struct conn_s *connptr, struct request_s *request) "Established connection to %s proxy \"%s\" using file descriptor %d.", proxy_type_name(cur_upstream->type), cur_upstream->host, connptr->server_fd); - if (cur_upstream->type == SOCKS4_TYPE) { + if (cur_upstream->type == PT_SOCKS4) { buff[0] = 4; /* socks version */ buff[1] = 1; /* connect command */ @@ -1308,7 +1308,7 @@ connect_to_upstream_proxy(struct conn_s *connptr, struct request_s *request) if (buff[0]!=0 || buff[1]!=90) return -1; - } else if (cur_upstream->type == SOCKS5_TYPE) { + } else if (cur_upstream->type == PT_SOCKS5) { /* init */ buff[0] = 5; /* socks version */ @@ -1404,7 +1404,7 @@ connect_to_upstream (struct conn_s *connptr, struct request_s *request) return -1; } - if (cur_upstream->type != HTTP_TYPE) + if (cur_upstream->type != PT_HTTP) return connect_to_upstream_proxy(connptr, request); log_message (LOG_CONN, diff --git a/src/upstream.c b/src/upstream.c index 03a6b8e..0c6b14e 100644 --- a/src/upstream.c +++ b/src/upstream.c @@ -35,9 +35,10 @@ const char * proxy_type_name(proxy_type type) { switch(type) { - case HTTP_TYPE: return "http"; - case SOCKS4_TYPE: return "socks4"; - case SOCKS5_TYPE: return "socks5"; + case PT_NONE: return "none"; + case PT_HTTP: return "http"; + case PT_SOCKS4: return "socks4"; + case PT_SOCKS5: return "socks5"; default: return "unknown"; } } @@ -63,7 +64,7 @@ static struct upstream *upstream_build (const char *host, int port, const char * up->host = up->domain = up->ua.user = up->pass = NULL; up->ip = up->mask = 0; if (user) { - if (type == HTTP_TYPE) { + if (type == PT_HTTP) { char b[BASE64ENC_BYTES((256+2)-1) + 1]; ssize_t ret; ret = basicauth_string(user, pass, b, sizeof b); diff --git a/src/upstream.h b/src/upstream.h index 9b664c8..c112784 100644 --- a/src/upstream.h +++ b/src/upstream.h @@ -31,7 +31,13 @@ * Even if upstream support is not compiled into tinyproxy, this * structure still needs to be defined. */ -typedef enum {HTTP_TYPE, SOCKS4_TYPE, SOCKS5_TYPE} proxy_type; +typedef enum proxy_type { + PT_NONE = 0, + PT_HTTP, + PT_SOCKS4, + PT_SOCKS5 +} proxy_type; + struct upstream { struct upstream *next; char *domain; /* optional */ From 9cde492d686ec77d5cfe7d98dfa7bddfe9c477e4 Mon Sep 17 00:00:00 2001 From: rofl0r Date: Sun, 25 Feb 2018 17:02:15 +0000 Subject: [PATCH 25/47] configure.ac: remove -pedantic --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index c3d4ac6..6b40679 100644 --- a/configure.ac +++ b/configure.ac @@ -173,7 +173,7 @@ AC_CHECK_FUNCS([inet_ntoa strdup]) AC_CHECK_FUNCS([strlcpy strlcat setgroups]) dnl Enable extra warnings -DESIRED_FLAGS="-fdiagnostics-show-option -Wall -Wextra -Wno-unused-parameter -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations -Wfloat-equal -Wundef -Wformat=2 -Wlogical-op -Wmissing-include-dirs -Wformat-nonliteral -Wold-style-definition -Wpointer-arith -Waggregate-return -Winit-self -Wpacked --std=c89 -ansi -pedantic -Wno-overlength-strings -Wno-long-long -Wno-overlength-strings -Wdeclaration-after-statement -Wredundant-decls -Wmissing-noreturn -Wshadow -Wendif-labels -Wcast-qual -Wcast-align -Wwrite-strings -Wp,-D_FORTIFY_SOURCE=2 -fno-common" +DESIRED_FLAGS="-fdiagnostics-show-option -Wall -Wextra -Wno-unused-parameter -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations -Wfloat-equal -Wundef -Wformat=2 -Wlogical-op -Wmissing-include-dirs -Wformat-nonliteral -Wold-style-definition -Wpointer-arith -Waggregate-return -Winit-self -Wpacked --std=c89 -ansi -Wno-overlength-strings -Wno-long-long -Wno-overlength-strings -Wdeclaration-after-statement -Wredundant-decls -Wmissing-noreturn -Wshadow -Wendif-labels -Wcast-qual -Wcast-align -Wwrite-strings -Wp,-D_FORTIFY_SOURCE=2 -fno-common" if test -n "${MAINTAINER_MODE_FALSE}"; then DESIRED_FLAGS="-Werror $DESIRED_FLAGS" From 057cf068058e99b47734898268c8c77861b05136 Mon Sep 17 00:00:00 2001 From: rofl0r Date: Sun, 25 Feb 2018 17:14:24 +0000 Subject: [PATCH 26/47] config: unify upstream syntax for http,socks4,socks5 and none closes #50 --- etc/tinyproxy.conf.in | 37 +++++++++++++----------- src/conf.c | 65 ++++++++++++++++++++----------------------- src/upstream.c | 2 +- 3 files changed, 52 insertions(+), 52 deletions(-) diff --git a/etc/tinyproxy.conf.in b/etc/tinyproxy.conf.in index ac16efe..54024cb 100644 --- a/etc/tinyproxy.conf.in +++ b/etc/tinyproxy.conf.in @@ -140,32 +140,37 @@ LogLevel Info # The upstream rules allow you to selectively route upstream connections # based on the host/domain of the site being accessed. # +# Syntax: upstream type (user:pass@)ip:port ("domain") +# Or: upstream none "domain" +# The parts in parens are optional. +# Possible types are http, socks4, socks5, none +# # For example: # # connection to test domain goes through testproxy -# upstream testproxy:8008 ".test.domain.invalid" -# upstream testproxy:8008 ".our_testbed.example.com" -# upstream testproxy:8008 "192.168.128.0/255.255.254.0" +# upstream http testproxy:8008 ".test.domain.invalid" +# upstream http testproxy:8008 ".our_testbed.example.com" +# upstream http testproxy:8008 "192.168.128.0/255.255.254.0" # # # upstream proxy using basic authentication -# upstream user:pass@testproxy:8008 ".test.domain.invalid" +# upstream http user:pass@testproxy:8008 ".test.domain.invalid" # # # no upstream proxy for internal websites and unqualified hosts -# no upstream ".internal.example.com" -# no upstream "www.example.com" -# no upstream "10.0.0.0/8" -# no upstream "192.168.0.0/255.255.254.0" -# no upstream "." +# upstream none ".internal.example.com" +# upstream none "www.example.com" +# upstream none "10.0.0.0/8" +# upstream none "192.168.0.0/255.255.254.0" +# upstream none "." # # # connection to these boxes go through their DMZ firewalls -# upstream cust1_firewall:8008 "testbed_for_cust1" -# upstream cust2_firewall:8008 "testbed_for_cust2" +# upstream http cust1_firewall:8008 "testbed_for_cust1" +# upstream http cust2_firewall:8008 "testbed_for_cust2" # # # default upstream is internet firewall -# upstream firewall.internal.example.com:80 +# upstream http firewall.internal.example.com:80 # -# You may also use SOCKS4/SOCKS5 upstream proxies by using upstream4/upstream5: -# upstream4 127.0.0.1:9050 -# upstream5 socksproxy:1080 +# You may also use SOCKS4/SOCKS5 upstream proxies: +# upstream socks4 127.0.0.1:9050 +# upstream socks5 socksproxy:1080 # # The LAST matching rule wins the route decision. As you can see, you # can use a host, or a domain: @@ -175,7 +180,7 @@ LogLevel Info # IP/bits matches network/mask # IP/mask matches network/mask # -#Upstream some.remote.proxy:port +#Upstream http some.remote.proxy:port # # MaxClients: This is the absolute highest number of threads which will diff --git a/src/conf.c b/src/conf.c index ca9764e..ac7354f 100644 --- a/src/conf.c +++ b/src/conf.c @@ -162,8 +162,6 @@ static HANDLE_FUNC (handle_xtinyproxy); #ifdef UPSTREAM_SUPPORT static HANDLE_FUNC (handle_upstream); -static HANDLE_FUNC (handle_upstream4); -static HANDLE_FUNC (handle_upstream5); static HANDLE_FUNC (handle_upstream_no); #endif @@ -254,25 +252,16 @@ struct { STDCONF ("reversepath", STR "(" WS STR ")?", handle_reversepath), #endif #ifdef UPSTREAM_SUPPORT - /* upstream is rather complicated */ { - BEGIN "(no" WS "upstream)" WS STR END, handle_upstream_no, NULL + BEGIN "(upstream)" WS "(none)" WS STR END, handle_upstream_no, NULL }, { - BEGIN "(upstream)" WS + BEGIN "(upstream)" WS "(http|socks4|socks5)" WS "(" ALNUM /*username*/ ":" ALNUM /*password*/ "@" ")?" "(" IP "|" ALNUM ")" ":" INT "(" WS STR ")?" END, handle_upstream, NULL }, - { - BEGIN "(upstream4)" WS "(" IP "|" ALNUM ")" ":" INT "(" WS STR - ")?" END, handle_upstream4, NULL - }, - { - BEGIN "(upstream5)" WS "(" IP "|" ALNUM ")" ":" INT "(" WS STR - ")?" END, handle_upstream5, NULL - }, #endif /* loglevel */ STDCONF ("loglevel", "(critical|error|warning|notice|connect|info)", @@ -1099,12 +1088,33 @@ static HANDLE_FUNC (handle_reversepath) #endif #ifdef UPSTREAM_SUPPORT -static int _handle_upstream(struct config_s* conf, const char* line, - regmatch_t match[], proxy_type type) + +static enum proxy_type pt_from_string(const char *s) +{ + static const char pt_map[][7] = { + [PT_NONE] = "none", + [PT_HTTP] = "http", + [PT_SOCKS4] = "socks4", + [PT_SOCKS5] = "socks5", + }; + unsigned i; + for (i = 0; i < sizeof(pt_map)/sizeof(pt_map[0]); i++) + if (!strcmp(pt_map[i], s)) + return i; + return PT_NONE; +} + +static HANDLE_FUNC (handle_upstream) { char *ip; - int port, mi = 3; - char *domain = 0, *user = 0, *pass = 0; + int port, mi = 2; + char *domain = 0, *user = 0, *pass = 0, *tmp; + enum proxy_type pt; + + tmp = get_string_arg (line, &match[mi]); + pt = pt_from_string(tmp); + safefree(tmp); + mi += 2; if (match[mi].rm_so != -1) user = get_string_arg (line, &match[mi]); @@ -1125,7 +1135,7 @@ static int _handle_upstream(struct config_s* conf, const char* line, if (match[mi].rm_so != -1) domain = get_string_arg (line, &match[mi]); - upstream_add (ip, port, domain, user, pass, type, &conf->upstream_list); + upstream_add (ip, port, domain, user, pass, pt, &conf->upstream_list); safefree (user); safefree (pass); @@ -1135,30 +1145,15 @@ static int _handle_upstream(struct config_s* conf, const char* line, return 0; } -static HANDLE_FUNC (handle_upstream) -{ - return _handle_upstream(conf, line, match, PT_HTTP); -} - -static HANDLE_FUNC (handle_upstream4) -{ - return _handle_upstream(conf, line, match, PT_SOCKS4); -} - -static HANDLE_FUNC (handle_upstream5) -{ - return _handle_upstream(conf, line, match, PT_SOCKS5); -} - static HANDLE_FUNC (handle_upstream_no) { char *domain; - domain = get_string_arg (line, &match[2]); + domain = get_string_arg (line, &match[3]); if (!domain) return -1; - upstream_add (NULL, 0, domain, 0, 0, PT_HTTP, &conf->upstream_list); + upstream_add (NULL, 0, domain, 0, 0, PT_NONE, &conf->upstream_list); safefree (domain); return 0; diff --git a/src/upstream.c b/src/upstream.c index 0c6b14e..38afacd 100644 --- a/src/upstream.c +++ b/src/upstream.c @@ -92,7 +92,7 @@ static struct upstream *upstream_build (const char *host, int port, const char * log_message (LOG_INFO, "Added upstream %s %s:%d for [default]", proxy_type_name(type), host, port); - } else if (host == NULL) { + } else if (host == NULL || type == PT_NONE) { if (!domain || domain[0] == '\0') { log_message (LOG_WARNING, "Nonsense no-upstream rule: empty domain"); From e78b4616077a4a37058aba6e5aae68534310511e Mon Sep 17 00:00:00 2001 From: rofl0r Date: Sun, 25 Feb 2018 18:18:53 +0000 Subject: [PATCH 27/47] update upstream syntax in manpage template --- docs/man5/tinyproxy.conf.txt.in | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/docs/man5/tinyproxy.conf.txt.in b/docs/man5/tinyproxy.conf.txt.in index e40135b..8f73720 100644 --- a/docs/man5/tinyproxy.conf.txt.in +++ b/docs/man5/tinyproxy.conf.txt.in @@ -144,21 +144,25 @@ The possible keywords and their descriptions are as follows: `X-Tinyproxy` containing the client's IP address to the request. *Upstream*:: -*No Upstream*:: This option allows you to set up a set of rules for deciding whether an upstream proxy server is to be used, based on the host or domain of the site being accessed. The rules are stored in the order encountered in the configuration file and the - LAST matching rule wins. There are three possible forms for - specifying upstream rules: + LAST matching rule wins. The following forms for specifying upstream + rules exist: - * 'upstream host:port' turns proxy upstream support on generally. + * 'upstream type host:port' turns proxy upstream support on generally. - * 'upstream host:port "site_spec"' turns on the upstream proxy for - the sites matching `site_spec`. + * 'upstream type user:pass@host:port' does the same, but uses the + supplied credentials for authentication. - * 'no upstream "site_spec"' turns off upstream support for sites + * 'upstream type host:port "site_spec"' turns on the upstream proxy + for the sites matching `site_spec`. + + `type` can be one of `http`, `socks4`, `socks5`, `none`. + + * 'upstream none "site_spec"' turns off upstream support for sites matching `site_spec`. The site can be specified in various forms as a hostname, domain From b8c6a2127de637c2c41eaf5d9b61c857116690e6 Mon Sep 17 00:00:00 2001 From: rofl0r Date: Mon, 26 Feb 2018 00:13:58 +0000 Subject: [PATCH 28/47] implement user/password auth for socks5 upstream proxy just like the rest of the socks code, this was stolen from proxychains-ng, of which i'm happen to be the maintainer of, so it's not an issue (the licenses are identical, too). --- src/reqs.c | 40 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/src/reqs.c b/src/reqs.c index a71cd47..202f77f 100644 --- a/src/reqs.c +++ b/src/reqs.c @@ -1285,9 +1285,15 @@ connect_to_upstream_proxy(struct conn_s *connptr, struct request_s *request) unsigned len; unsigned char buff[512]; /* won't use more than 7 + 255 */ unsigned short port; + size_t ulen, passlen; + struct hostent *host; struct upstream *cur_upstream = connptr->upstream_proxy; + ulen = cur_upstream->ua.user ? strlen(cur_upstream->ua.user) : 0; + passlen = cur_upstream->pass ? strlen(cur_upstream->pass) : 0; + + log_message(LOG_CONN, "Established connection to %s proxy \"%s\" using file descriptor %d.", proxy_type_name(cur_upstream->type), cur_upstream->host, connptr->server_fd); @@ -1311,15 +1317,43 @@ connect_to_upstream_proxy(struct conn_s *connptr, struct request_s *request) } else if (cur_upstream->type == PT_SOCKS5) { /* init */ + int n_methods = ulen ? 2 : 1; buff[0] = 5; /* socks version */ - buff[1] = 1; /* number of methods */ + buff[1] = n_methods; /* number of methods */ buff[2] = 0; /* no auth method */ - if (3 != safe_write(connptr->server_fd, buff, 3)) + if (ulen) buff[3] = 2; /* auth method -> username / password */ + if (2+n_methods != safe_write(connptr->server_fd, buff, 2+n_methods)) return -1; if (2 != safe_read(connptr->server_fd, buff, 2)) return -1; - if (buff[0]!=5 || buff[1]!=0) + if (buff[0] != 5 || (buff[1] != 0 && buff[1] != 2)) return -1; + + if (buff[1] == 2) { + /* authentication */ + char in[2]; + char out[515]; + char *cur = out; + size_t c; + *cur++ = 1; /* version */ + c = ulen & 0xFF; + *cur++ = c; + memcpy(cur, cur_upstream->ua.user, c); + cur += c; + c = passlen & 0xFF; + *cur++ = c; + memcpy(cur, cur_upstream->pass, c); + cur += c; + + if((cur - out) != safe_write(connptr->server_fd, out, cur - out)) + return -1; + + if(2 != safe_read(connptr->server_fd, in, 2)) + return -1; + if(in[0] != 5 || in[1] != 0) { + return -1; + } + } /* connect */ buff[0] = 5; /* socks version */ buff[1] = 1; /* connect */ From a53f62a212947600a785b3e94db55a856325920e Mon Sep 17 00:00:00 2001 From: rofl0r Date: Sun, 25 Feb 2018 23:42:31 +0000 Subject: [PATCH 29/47] enable transparent proxy by default by having all features turned on by default, the binary is only slightly bigger, but users of binary distros get the whole package and don't need to compile tinyproxy by hand if they need a feature that wasn't compiled in. it also prevents the confusion from getting syntax errors when a config file using those features is parsed. another advantage is that by enabling them these features may actually get some more testing. --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 6b40679..66e6031 100644 --- a/configure.ac +++ b/configure.ac @@ -124,8 +124,8 @@ dnl Include the transparent proxy support AH_TEMPLATE([TRANSPARENT_PROXY], [Include support for using tinyproxy as a transparent proxy.]) TP_ARG_ENABLE(transparent, - [Enable transparent proxying code (default is NO)], - no) + [Enable transparent proxying code (default is YES)], + yes) if test x"$transparent_enabled" = x"yes"; then ADDITIONAL_OBJECTS="$ADDITIONAL_OBJECTS transparent-proxy.o" AC_DEFINE(TRANSPARENT_PROXY) From 09979629c03ae237617e7142594b5b9508be24a9 Mon Sep 17 00:00:00 2001 From: rofl0r Date: Tue, 27 Feb 2018 20:34:50 +0000 Subject: [PATCH 30/47] make bind option usable with transparent proxy too closes #15 for real. the previous patch that was merged[0] was halfbaked and only removed the warning part of the original patch from openwrt[1], but didn't actually activate bind support. further it invoked UB by removing the return value from the function, if transparent proxy support was compiled in. [0]: d97d486d53ce214ae952378308292f333b8c7a36 [1]: https://gitlab.labs.nic.cz/turris/openwrt-packages/commit/7c01da4a72e6f0b7613a86529547659ea4007eba --- src/conf.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/conf.c b/src/conf.c index ac7354f..5a87c68 100644 --- a/src/conf.c +++ b/src/conf.c @@ -876,7 +876,6 @@ static HANDLE_FUNC (handle_deny) static HANDLE_FUNC (handle_bind) { -#ifndef TRANSPARENT_PROXY int r = set_string_arg (&conf->bind_address, line, &match[2]); if (r) @@ -884,7 +883,6 @@ static HANDLE_FUNC (handle_bind) log_message (LOG_INFO, "Outgoing connections bound to IP %s", conf->bind_address); return 0; -#endif } static HANDLE_FUNC (handle_listen) From 8d0ea71486688323fff65bc3730bae209a70db7b Mon Sep 17 00:00:00 2001 From: rofl0r Date: Fri, 16 Mar 2018 15:21:20 +0000 Subject: [PATCH 31/47] install tinyproxy to bin/, not /sbin sbin/ is meant for programs only usable by root, but in tinyproxy's case, regular users can and *should* use tinyproxy; meaning it is preferable from a security PoV to use tinyproxy as regular user. --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile.am b/src/Makefile.am index 565eb4d..18b4715 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -17,7 +17,7 @@ pkgsysconfdir = $(sysconfdir)/$(PACKAGE) -sbin_PROGRAMS = tinyproxy +bin_PROGRAMS = tinyproxy AM_CPPFLAGS = \ -DSYSCONFDIR=\"${pkgsysconfdir}\" \ From badb6435d616066a8648152a24a09f9e090a6e5e Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 16 Nov 2017 01:53:21 +0100 Subject: [PATCH 32/47] upstream: Fix case of empty string domain. Found by compiler note. Signed-off-by: Michael Adam --- src/upstream.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/upstream.c b/src/upstream.c index 38afacd..327b727 100644 --- a/src/upstream.c +++ b/src/upstream.c @@ -124,7 +124,7 @@ static struct upstream *upstream_build (const char *host, int port, const char * log_message (LOG_INFO, "Added no-upstream for %s", domain); } else { if (!host || host[0] == '\0' || port < 1 || !domain - || domain == '\0') { + || domain[0] == '\0') { log_message (LOG_WARNING, "Nonsense upstream rule: invalid parameters"); goto fail; From ae0cbfe3f2f6d6c2ac3734b7b2026c9a8502c200 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 23 Mar 2018 02:03:54 +0100 Subject: [PATCH 33/47] html-error: Make a switch fallthrough explicit This silences a gcc v7 compile warning. Signed-off-by: Michael Adam --- src/html-error.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/html-error.c b/src/html-error.c index 0c011a7..625a586 100644 --- a/src/html-error.c +++ b/src/html-error.c @@ -132,6 +132,7 @@ send_html_file (FILE *infile, struct conn_s *connptr) } else in_variable = 0; + /* FALL THROUGH */ default: if (!in_variable) { r = write_message (connptr->client_fd, From 0aad2f5b92c7690a25f849ffa0f7a41ee8b5ff46 Mon Sep 17 00:00:00 2001 From: rofl0r Date: Wed, 28 Mar 2018 02:02:45 +0100 Subject: [PATCH 34/47] fix basicauth string comparison closes #160 --- src/basicauth.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/basicauth.c b/src/basicauth.c index 7092657..d6c2420 100644 --- a/src/basicauth.c +++ b/src/basicauth.c @@ -83,16 +83,15 @@ void basicauth_add (vector_t authlist, int basicauth_check (vector_t authlist, const char *authstring) { ssize_t vl, i; - size_t al, el; + size_t el; const char* entry; vl = vector_length (authlist); if (vl == -EINVAL) return 0; - al = strlen (authstring); for (i = 0; i < vl; i++) { entry = vector_getentry (authlist, i, &el); - if (strncmp (authstring, entry, al) == 0) + if (strcmp (authstring, entry) == 0) return 1; } return 0; From c651664720d1fc21aeb36ca8dbb625a874af1d97 Mon Sep 17 00:00:00 2001 From: rofl0r Date: Tue, 29 May 2018 19:17:41 +0100 Subject: [PATCH 35/47] fix socks5 upstream user/pass subnegotiation check RFC 1929 specifies that the user/pass auth subnegotation repurposes the version field for the version of that specification, which is 1, not 5. however there's quite a good deal of software out there which got it wrong and replies with version 5 to a successful authentication, so let's just accept both forms - other socks5 client programs like curl do the same. closes #172 --- src/reqs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/reqs.c b/src/reqs.c index 202f77f..bbdcc74 100644 --- a/src/reqs.c +++ b/src/reqs.c @@ -1350,7 +1350,7 @@ connect_to_upstream_proxy(struct conn_s *connptr, struct request_s *request) if(2 != safe_read(connptr->server_fd, in, 2)) return -1; - if(in[0] != 5 || in[1] != 0) { + if(in[1] != 0 || !(in[0] == 5 || in[0] == 1)) { return -1; } } From ec95d8b553e54dd4ed82d92f8e27b7ef29c55c77 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sat, 1 Sep 2018 01:26:42 +0200 Subject: [PATCH 36/47] configure: remove unused variables Signed-off-by: Michael Adam --- configure.ac | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/configure.ac b/configure.ac index 66e6031..a47316b 100644 --- a/configure.ac +++ b/configure.ac @@ -13,11 +13,6 @@ m4_define([tinyproxy_version], [tinyproxy_real_version]) # For overriding the version string. Comment out if not needed. # m4_define([tinyproxy_version], [1.9.0]) -m4_define([tinyproxy_unstable], - m4_if(m4_eval(tinyproxy_minor_version % 2), [1], [yes], [no])) -m4_define([tinyproxy_stable], - m4_if(m4_eval(tinyproxy_minor_version % 2), [0], [yes], [no])) - AC_INIT([Tinyproxy], [tinyproxy_version], [https://tinyproxy.github.io/], [tinyproxy]) @@ -29,19 +24,6 @@ AC_CONFIG_MACRO_DIR([m4macros]) m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])]) -TINYPROXY_MAJOR_VERSION=tinyproxy_major_version -TINYPROXY_MINOR_VERSION=tinyproxy_minor_version -TINYPROXY_MICRO_VERSION=tinyproxy_micro_version -TINYPROXY_REAL_VERSION=tinyproxy_real_version -TINYPROXY_VERSION=tinyproxy_version -TINYPROXY_UNSTABLE=tinyproxy_unstable -AC_SUBST(TINYPROXY_MAJOR_VERSION) -AC_SUBST(TINYPROXY_MINOR_VERSION) -AC_SUBST(TINYPROXY_MICRO_VERSION) -AC_SUBST(TINYPROXY_REAL_VERSION) -AC_SUBST(TINYPROXY_VERSION) -AC_SUBST(TINYPROXY_UNSTABLE) - dnl Temporarily defined here until we get tinyproxy-version.h AC_DEFINE(TINYPROXY_VERSION, "tinyproxy_version", [Tinyproxy version number]) From 89b2c68b2bf568dbedff52bc813bce39c8e6d027 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sat, 1 Sep 2018 01:45:27 +0200 Subject: [PATCH 37/47] NEWS: just mention to use git log Signed-off-by: Michael Adam --- NEWS | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/NEWS b/NEWS index 550e7fe..c0fddc8 100644 --- a/NEWS +++ b/NEWS @@ -1,12 +1 @@ -Tinyproxy NEWS -============== - -Version 1.9.0 -------------- - -Bugs fixed -~~~~~~~~~~ - -Contributors -~~~~~~~~~~~~ - +See git log for recent changes in Tinyproxy. From 56f30a438643ec3ec82d1ade7d8bed394120c0df Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sat, 1 Sep 2018 02:03:09 +0200 Subject: [PATCH 38/47] main: remove the "-l" switch to display the license and authors Signed-off-by: Michael Adam --- docs/man8/tinyproxy.txt.in | 3 -- src/main.c | 57 +------------------------------------- 2 files changed, 1 insertion(+), 59 deletions(-) diff --git a/docs/man8/tinyproxy.txt.in b/docs/man8/tinyproxy.txt.in index e259dcb..b1c4a9a 100644 --- a/docs/man8/tinyproxy.txt.in +++ b/docs/man8/tinyproxy.txt.in @@ -40,9 +40,6 @@ OPTIONS *-h*:: Display a short help screen of command line arguments and exit. -*-l*:: - Display the licensing agreement. - *-v*:: Display version information and exit. diff --git a/src/main.c b/src/main.c index 35ff704..43170c5 100644 --- a/src/main.c +++ b/src/main.c @@ -32,7 +32,6 @@ #include "main.h" #include "anonymous.h" -#include "authors.h" #include "buffer.h" #include "conf.h" #include "daemon.h" @@ -87,55 +86,6 @@ display_version (void) printf ("%s %s\n", PACKAGE, VERSION); } -/* - * Display the copyright and license for this program. - */ -static void -display_license (void) -{ - const char * const *authors; - const char * const *documenters; - - display_version (); - - printf ("\ -\n\ - Copyright 1998 Steven Young (sdyoung@well.com)\n\ - Copyright 1998-2002 Robert James Kaes (rjkaes@users.sourceforge.net)\n\ - Copyright 1999 George Talusan (gstalusan@uwaterloo.ca)\n\ - Copyright 2000 Chris Lightfoot (chris@ex-parrot.com)\n\ - Copyright 2009-2010 Mukund Sivaraman (muks@banu.com)\n\ - Copyright 2009-2010 Michael Adam (obnox@samba.org)\n\ -\n\ - This program is free software; you can redistribute it and/or modify\n\ - it under the terms of the GNU General Public License as published by\n\ - the Free Software Foundation; either version 2, or (at your option)\n\ - any later version.\n\ -\n\ - This program is distributed in the hope that it will be useful,\n\ - but WITHOUT ANY WARRANTY; without even the implied warranty of\n\ - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n\ - GNU General Public License for more details.\n\ -\n\ - You should have received a copy of the GNU General Public License\n\ - along with this program; if not, write to the Free Software\n\ - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.\n\ -\n"); - - printf ("\nAUTHORS:\n"); - for (authors = authors_get_authors (); *authors; authors++) { - printf (" %s\n", *authors); - } - - printf ("\nDOCUMENTERS:\n"); - for (documenters = authors_get_documenters (); - *documenters; documenters++) { - printf (" %s\n", *documenters); - } - - printf ("\n"); -} - /* * Display usage to the user. */ @@ -150,7 +100,6 @@ display_usage (void) " -d Do not daemonize (run in foreground).\n" " -c FILE Use an alternate configuration file.\n" " -h Display this usage information.\n" - " -l Display the license.\n" " -v Display version information.\n"); /* Display the modes compiled into tinyproxy */ @@ -224,16 +173,12 @@ process_cmdline (int argc, char **argv, struct config_s *conf) { int opt; - while ((opt = getopt (argc, argv, "c:vldh")) != EOF) { + while ((opt = getopt (argc, argv, "c:vdh")) != EOF) { switch (opt) { case 'v': display_version (); exit (EX_OK); - case 'l': - display_license (); - exit (EX_OK); - case 'd': conf->godaemon = FALSE; break; From a5e6d343d78462f9233015af9b7b0a1911d5e6db Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sat, 1 Sep 2018 02:07:39 +0200 Subject: [PATCH 39/47] Remove unused authors.c/authors.h and generation mechanism. Signed-off-by: Michael Adam --- src/Makefile.am | 14 ----------- src/authors.c | 50 -------------------------------------- src/authors.h | 30 ----------------------- src/authors.xsl | 64 ------------------------------------------------- 4 files changed, 158 deletions(-) delete mode 100644 src/authors.c delete mode 100644 src/authors.h delete mode 100644 src/authors.xsl diff --git a/src/Makefile.am b/src/Makefile.am index 18b4715..af2f621 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -26,7 +26,6 @@ AM_CPPFLAGS = \ tinyproxy_SOURCES = \ acl.c acl.h \ anonymous.c anonymous.h \ - authors.c authors.h \ buffer.c buffer.h \ child.c child.h \ common.h \ @@ -56,16 +55,3 @@ EXTRA_tinyproxy_SOURCES = filter.c filter.h \ transparent-proxy.c transparent-proxy.h tinyproxy_DEPENDENCIES = @ADDITIONAL_OBJECTS@ tinyproxy_LDADD = @ADDITIONAL_OBJECTS@ - -EXTRA_DIST = \ - authors.xsl - -authors.c: $(top_srcdir)/authors.xml $(srcdir)/authors.xsl -if HAVE_XSLTPROC - $(AM_V_GEN) $(XSLTPROC) $(srcdir)/authors.xsl $< > $(@) || rm -f $(@) -else - @echo "*** xsltproc is required to regenerate $(@) ***"; exit 1; -endif - -BUILT_SOURCES = \ - authors.c diff --git a/src/authors.c b/src/authors.c deleted file mode 100644 index 496df93..0000000 --- a/src/authors.c +++ /dev/null @@ -1,50 +0,0 @@ - -/* NOTE: This file is auto-generated from authors.xml, do not edit it. */ - -#include "authors.h" - -static const char * const authors[] = -{ - "Andrew Stribblehill", - "Chris Lightfoot", - "Daniel Egger", - "David Shanks", - "Dmitry Semyonov", - "George Talusan", - "James E. Flemer", - "Jeremy Hinegardner", - "John van der Kamp", - "Jordi Mallach", - "Kim Holviala", - "Mathew Mrosko", - "Matthew Dempsky", - "Michael Adam", - "Moritz Muehlenhoff", - "Mukund Sivaraman", - "Petr Lampa", - "Robert James Kaes", - "Steven Young", - NULL -}; - -static const char * const documenters[] = -{ - "Marc Silver", - "Michael Adam", - "Mukund Sivaraman", - "Robert James Kaes", - "Steven Young", - NULL -}; - -const char * const * -authors_get_authors (void) -{ - return authors; -} - -const char * const * -authors_get_documenters (void) -{ - return documenters; -} diff --git a/src/authors.h b/src/authors.h deleted file mode 100644 index 10e5110..0000000 --- a/src/authors.h +++ /dev/null @@ -1,30 +0,0 @@ -/* tinyproxy - A fast light-weight HTTP proxy - * Copyright (C) 2010 Mukund Sivaraman - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef __AUTHORS_H__ -#define __AUTHORS_H__ - -#include "common.h" - -const char * const * -authors_get_authors (void); - -const char * const * -authors_get_documenters (void); - -#endif /* __AUTHORS_H__ */ diff --git a/src/authors.xsl b/src/authors.xsl deleted file mode 100644 index 1388b9a..0000000 --- a/src/authors.xsl +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - - - - - - - - - - -/* NOTE: This file is auto-generated from authors.xml, do not edit it. */ - -#include "authors.h" - -static const char * const authors[] = -{ - - - - - NULL -}; - - - -static const char * const documenters[] = -{ - - - - - NULL -}; - -const char * const * -authors_get_authors (void) -{ - return authors; -} - -const char * const * -authors_get_documenters (void) -{ - return documenters; -} - - - - "", - - - From 3eb3c2c099a6097cd821e96c22a247648784c14b Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sat, 1 Sep 2018 02:25:50 +0200 Subject: [PATCH 40/47] Remove xml-based AUTHORS mechanism. AUTHORS is checked in. Signed-off-by: Michael Adam --- Makefile.am | 20 +------------------ authors.dtd | 12 ----------- authors.xml | 36 --------------------------------- authors.xsl | 57 ----------------------------------------------------- 4 files changed, 1 insertion(+), 124 deletions(-) delete mode 100644 authors.dtd delete mode 100644 authors.xml delete mode 100644 authors.xsl diff --git a/Makefile.am b/Makefile.am index 9d62d2c..e9113c2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -9,22 +9,7 @@ SUBDIRS = \ # tools want this on a single line ACLOCAL_AMFLAGS = -I m4macros -AUTHORS: authors.xml authors.xsl -if HAVE_XSLTPROC - $(AM_V_GEN) $(XSLTPROC) authors.xsl $< > $(@) || rm -f $(@) -else - @echo "*** xsltproc is required to regenerate $(@) ***"; exit 1; -endif - -validate-authors: -if HAVE_XMLLINT - @$(XMLLINT) --noout --path $(srcdir) --valid authors.xml || \ - ( echo "*** authors.xml IS INVALID ***"; exit 1; ) -endif - -all-local: AUTHORS - -check-local: validate-authors +all-local: dist_doc_DATA = \ AUTHORS \ @@ -33,9 +18,6 @@ dist_doc_DATA = \ README.md EXTRA_DIST = \ - authors.dtd \ - authors.xml \ - authors.xsl \ autogen.sh \ tinyproxy-indent.sh \ TODO diff --git a/authors.dtd b/authors.dtd deleted file mode 100644 index 77d43c5..0000000 --- a/authors.dtd +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - diff --git a/authors.xml b/authors.xml deleted file mode 100644 index 7fc94f2..0000000 --- a/authors.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - Andrew Stribblehill - Chris Lightfoot - Daniel Egger - David Shanks - Dmitry Semyonov - George Talusan - James E. Flemer - Jeremy Hinegardner - John van der Kamp - Jordi Mallach - Kim Holviala - Marc Silver - Mathew Mrosko - Matthew Dempsky - Michael Adam - Moritz Muehlenhoff - Mukund Sivaraman - Petr Lampa - Robert James Kaes - Steven Young - - diff --git a/authors.xsl b/authors.xsl deleted file mode 100644 index 77ba4e0..0000000 --- a/authors.xsl +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - - - - - - - - - - Tinyproxy AUTHORS -================= - -//// -This file is generated from authors.xml, do not edit it directly. -//// - -Coding ------- - -The following people have contributed code to Tinyproxy: - - - - - - - -Documentation -------------- - -The following people have helped to document Tinyproxy: - - - - - - - - - - * - - - - From 4c9289802a8c1f73fed7fc43a70c5f57a9617057 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sat, 1 Sep 2018 03:32:11 +0200 Subject: [PATCH 41/47] scripts: add a script to generate the AUTHORS file from git Signed-off-by: Michael Adam --- scripts/gen-authors.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100755 scripts/gen-authors.sh diff --git a/scripts/gen-authors.sh b/scripts/gen-authors.sh new file mode 100755 index 0000000..671f0c1 --- /dev/null +++ b/scripts/gen-authors.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +SCRIPT_DIR="$(cd "$(dirname "${0}")" && pwd)" +BASE_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)" +AUTHORS_FILE="${BASE_DIR}/AUTHORS" + +type git > /dev/null || exit +test -d "${BASE_DIR}/.git" || exit + +git log --all --format='%aN' | sort -u > "${AUTHORS_FILE}" From e2a92ea33475280b631c326e8082454e49047086 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sat, 1 Sep 2018 02:38:46 +0200 Subject: [PATCH 42/47] Update AUTHORS Signed-off-by: Michael Adam --- AUTHORS | 82 +++++++++++++++++++++++++++------------------------------ 1 file changed, 39 insertions(+), 43 deletions(-) diff --git a/AUTHORS b/AUTHORS index 9c82e40..d0e6b30 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,43 +1,39 @@ -Tinyproxy AUTHORS -================= - -//// -This file is generated from authors.xml, do not edit it directly. -//// - -Coding ------- - -The following people have contributed code to Tinyproxy: - - * Andrew Stribblehill - * Chris Lightfoot - * Daniel Egger - * David Shanks - * Dmitry Semyonov - * George Talusan - * James E. Flemer - * Jeremy Hinegardner - * John van der Kamp - * Jordi Mallach - * Kim Holviala - * Mathew Mrosko - * Matthew Dempsky - * Michael Adam - * Moritz Muehlenhoff - * Mukund Sivaraman - * Petr Lampa - * Robert James Kaes - * Steven Young - - -Documentation -------------- - -The following people have helped to document Tinyproxy: - - * Marc Silver - * Michael Adam - * Mukund Sivaraman - * Robert James Kaes - * Steven Young +Andrew Stribblehill +bertliao +Bob Showalter +Brian Cain +cvs2svn +Daniel Egger +Daniel M. Drucker +David Shanks +Dmitry Semyonov +dmz-uk +Drew G. Wallace +Frank Morgner +gary-wzl77 +Gaudenz Steinlin +goba62000374 +Gonzalo Tornaria +Greg +Jeremy Hinegardner +John Spencer +John van der Kamp +John Weldon +Jordi +Jordi Mallach +Julien Hartmann +kikuchan +Mathew Mrosko +Matthew Dempsky +Michael Adam +Mike Mead +Mukund Sivaraman +Pablo Panero +Peter H. Froehlich +Robert James Kaes +rofl0r +Stephan Leemburg +Steven Conaway +Steven Young +Valen Blanco +Vladimir Belov From 8333a4bb1a1b0599137a4fc7cf3d8ea590764082 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sat, 1 Sep 2018 04:02:36 +0200 Subject: [PATCH 43/47] docs: update the copyright notice in the manpages Signed-off-by: Michael Adam --- docs/man5/tinyproxy.conf.txt.in | 5 +---- docs/man8/tinyproxy.txt.in | 5 +---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/docs/man5/tinyproxy.conf.txt.in b/docs/man5/tinyproxy.conf.txt.in index 8f73720..b3b94ec 100644 --- a/docs/man5/tinyproxy.conf.txt.in +++ b/docs/man5/tinyproxy.conf.txt.in @@ -364,10 +364,7 @@ This manpage was written by the Tinyproxy project team. COPYRIGHT --------- -Copyright (c) 1998-2000 Steven Young; -Copyright (c) 2000-2001 Robert James Kaes; -Copyright (c) 2009-2010 Mukund Sivaraman; -Copyright (c) 2009-2010 Michael Adam. +Copyright (c) 1998-2018 the Tinyproxy authors. This program is distributed under the terms of the GNU General Public License version 2 or above. See the COPYING file for additional diff --git a/docs/man8/tinyproxy.txt.in b/docs/man8/tinyproxy.txt.in index b1c4a9a..ba6cc15 100644 --- a/docs/man8/tinyproxy.txt.in +++ b/docs/man8/tinyproxy.txt.in @@ -150,10 +150,7 @@ This manpage was written by the Tinyproxy project team. COPYRIGHT --------- -Copyright (c) 1998-2000 Steven Young; -Copyright (c) 2000-2001 Robert James Kaes; -Copyright (c) 2009-2010 Mukund Sivaraman; -Copyright (c) 2009-2010 Michael Adam. +Copyright (c) 1998-2018 the Tinyproxy authors. This program is distributed under the terms of the GNU General Public License version 2 or above. See the COPYING file for additional From a662c11b8d106e0a2f3379b89739ed4770c5bbd3 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sat, 1 Sep 2018 02:40:17 +0200 Subject: [PATCH 44/47] Release 1.10.0 Signed-off-by: Michael Adam --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index a47316b..48ee0b2 100644 --- a/configure.ac +++ b/configure.ac @@ -4,14 +4,14 @@ AC_PREREQ(2.54) m4_define([tinyproxy_major_version], [1]) -m4_define([tinyproxy_minor_version], [9]) +m4_define([tinyproxy_minor_version], [10]) m4_define([tinyproxy_micro_version], [0]) m4_define([tinyproxy_real_version], [tinyproxy_major_version.tinyproxy_minor_version.tinyproxy_micro_version]) m4_define([tinyproxy_version], [tinyproxy_real_version]) # For overriding the version string. Comment out if not needed. -# m4_define([tinyproxy_version], [1.9.0]) +# m4_define([tinyproxy_version], [1.10.0]) AC_INIT([Tinyproxy], [tinyproxy_version], [https://tinyproxy.github.io/], From 9f4ed46c0adf6ce6cb8dd44aff611448b64a37a7 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 4 Sep 2018 01:23:01 +0200 Subject: [PATCH 45/47] build: add new version mechanism based on VERSION file and a version.sh script If this is a git checkout, and git is available, then git describe is used. Otherwise, the new checked in VERSION file is taken for the version. This mechanism uses a version.sh script inspired by http://git.musl-libc.org/cgit/musl/tree/tools/version.sh Signed-off-by: Michael Adam --- Makefile.am | 6 ++++-- VERSION | 1 + configure.ac | 11 ++--------- scripts/Makefile.am | 2 ++ scripts/version.sh | 15 +++++++++++++++ 5 files changed, 24 insertions(+), 11 deletions(-) create mode 100644 VERSION create mode 100644 scripts/Makefile.am create mode 100755 scripts/version.sh diff --git a/Makefile.am b/Makefile.am index e9113c2..4a3ead6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -4,7 +4,8 @@ SUBDIRS = \ etc \ docs \ m4macros \ - tests + tests \ + scripts # tools want this on a single line ACLOCAL_AMFLAGS = -I m4macros @@ -20,7 +21,8 @@ dist_doc_DATA = \ EXTRA_DIST = \ autogen.sh \ tinyproxy-indent.sh \ - TODO + TODO \ + VERSION test: all ./tests/scripts/run_tests.sh diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..81c871d --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +1.10.0 diff --git a/configure.ac b/configure.ac index 48ee0b2..1e71e35 100644 --- a/configure.ac +++ b/configure.ac @@ -3,15 +3,7 @@ AC_PREREQ(2.54) -m4_define([tinyproxy_major_version], [1]) -m4_define([tinyproxy_minor_version], [10]) -m4_define([tinyproxy_micro_version], [0]) -m4_define([tinyproxy_real_version], - [tinyproxy_major_version.tinyproxy_minor_version.tinyproxy_micro_version]) -m4_define([tinyproxy_version], [tinyproxy_real_version]) - -# For overriding the version string. Comment out if not needed. -# m4_define([tinyproxy_version], [1.10.0]) +m4_define([tinyproxy_version], esyscmd(sh scripts/version.sh | tr -d '\n')) AC_INIT([Tinyproxy], [tinyproxy_version], [https://tinyproxy.github.io/], @@ -227,6 +219,7 @@ docs/man8/tinyproxy.txt m4macros/Makefile tests/Makefile tests/scripts/Makefile +scripts/Makefile ]) AC_OUTPUT diff --git a/scripts/Makefile.am b/scripts/Makefile.am new file mode 100644 index 0000000..4876c5d --- /dev/null +++ b/scripts/Makefile.am @@ -0,0 +1,2 @@ +EXTRA_DIST = \ + version.sh diff --git a/scripts/version.sh b/scripts/version.sh new file mode 100755 index 0000000..9a965dc --- /dev/null +++ b/scripts/version.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +SCRIPT_DIR="$(cd "$(dirname "${0}")" && pwd)" +GIT_DIR="${SCRIPT_DIR}/../.git" + +if test -d "${GIT_DIR}" ; then + if type git >/dev/null 2>&1 ; then + git describe --match '[0-9]*.[0-9]*.[0-9]*' 2>/dev/null \ + | sed -e 's/-/-git-/' + else + sed 's/$/-git/' < VERSION + fi +else + cat VERSION +fi From 04f68e21e76047ed8a0747016d7f6f03e070fc59 Mon Sep 17 00:00:00 2001 From: rofl0r Date: Sat, 1 Sep 2018 03:27:45 +0100 Subject: [PATCH 46/47] tinyproxy.8: remove l flag from short options --- docs/man8/tinyproxy.txt.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/man8/tinyproxy.txt.in b/docs/man8/tinyproxy.txt.in index ba6cc15..54da867 100644 --- a/docs/man8/tinyproxy.txt.in +++ b/docs/man8/tinyproxy.txt.in @@ -12,7 +12,7 @@ tinyproxy - A light-weight HTTP proxy daemon SYNOPSIS -------- -*tinyproxy* [-vldch] +*tinyproxy* [-vdch] DESCRIPTION From f44d0f387b2e9bfcacf1c5ee15363fbc3a8e0e75 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 4 Sep 2018 01:32:09 +0200 Subject: [PATCH 47/47] build: Remove now unused TINYPROXY_UNSTABLE variable from configure Signed-off-by: Michael Adam --- configure.ac | 9 --------- 1 file changed, 9 deletions(-) diff --git a/configure.ac b/configure.ac index 1e71e35..6ddbcc0 100644 --- a/configure.ac +++ b/configure.ac @@ -19,15 +19,6 @@ m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])]) dnl Temporarily defined here until we get tinyproxy-version.h AC_DEFINE(TINYPROXY_VERSION, "tinyproxy_version", [Tinyproxy version number]) -# The symbol TINYPROXY_UNSTABLE is defined above for substitution in -# Makefiles and conditionally defined here as a preprocessor symbol -# and automake conditional. -if test "x$TINYPROXY_UNSTABLE" = "xyes"; then - AC_DEFINE(TINYPROXY_UNSTABLE, 1, - [Define to 1 if this is an unstable version of Tinyproxy]) -fi -AM_CONDITIONAL(TINYPROXY_UNSTABLE, test "x$TINYPROXY_UNSTABLE" = "xyes") - dnl Check if we're compiling on a weird platform :) AC_USE_SYSTEM_EXTENSIONS