From c2b82f3918f9d74d298e12bd02c5dc23d5e253b0 Mon Sep 17 00:00:00 2001 From: Timo Kluck Date: Sun, 3 Feb 2019 17:15:37 +0100 Subject: [PATCH] WIP: add naive support for pacparser --- configure.ac | 10 ++++++++ src/conf.c | 26 +++++++++++++++++++- src/conf.h | 3 +++ src/main.c | 5 ++++ src/reqs.c | 6 ++++- src/upstream.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/upstream.h | 7 ++++++ 7 files changed, 119 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 6ddbcc0f..778fe492 100644 --- a/configure.ac +++ b/configure.ac @@ -96,6 +96,16 @@ if test x"$transparent_enabled" = x"yes"; then AC_DEFINE(TRANSPARENT_PROXY) fi +dnl Include support for pacparser? +AH_TEMPLATE([PACPARSER_SUPPORT], + [Include support for the PacUpstream directive through the pacparser library]) +AC_ARG_WITH([pacparser], AS_HELP_STRING([--with-pacparser], [Add support for the PacUpstream directive through the pacparser library])) +if test "x$with_pacparser" = "xyes"; then + AC_CHECK_HEADERS([pacparser.h]) + LIBS+=-lpacparser + AC_DEFINE(PACPARSER_SUPPORT) +fi + # This is required to build test programs below AC_PROG_CC diff --git a/src/conf.c b/src/conf.c index 5ebf1790..c806b624 100644 --- a/src/conf.c +++ b/src/conf.c @@ -165,6 +165,9 @@ static HANDLE_FUNC (handle_xtinyproxy); #ifdef UPSTREAM_SUPPORT static HANDLE_FUNC (handle_upstream); static HANDLE_FUNC (handle_upstream_no); +#ifdef PACPARSER_SUPPORT +static HANDLE_FUNC (handle_pacupstream); +#endif #endif static void config_free_regex (void); @@ -264,6 +267,9 @@ struct { ":" INT "(" WS STR ")?" END, handle_upstream, NULL }, +#ifdef PACPARSER_SUPPORT + STDCONF ("pacupstream", STR, handle_pacupstream), +#endif #endif /* loglevel */ STDCONF ("loglevel", "(critical|error|warning|notice|connect|info)", @@ -1158,4 +1164,22 @@ static HANDLE_FUNC (handle_upstream_no) return 0; } -#endif + +#ifdef PACPARSER_SUPPORT + +static HANDLE_FUNC (handle_pacupstream) +{ + int res; + res = set_string_arg (&conf->pac_filename, line, &match[2]); + if (res != 0) + return res; + + pacparser_upstream_init (); + pacparser_upstream_load_script (conf->pac_filename); + + return res; +} + +#endif /* PACPARSER_SUPPORT */ + +#endif /* UPSTREAM_SUPPORT */ diff --git a/src/conf.h b/src/conf.h index beb2b01b..f0d9073d 100644 --- a/src/conf.h +++ b/src/conf.h @@ -66,6 +66,9 @@ struct config_s { #ifdef UPSTREAM_SUPPORT struct upstream *upstream_list; #endif /* UPSTREAM_SUPPORT */ +#ifdef PACPARSER_SUPPORT + char *pac_filename; +#endif /* PACPARSER_SUPPORT */ char *pidpath; unsigned int idletimeout; char *bind_address; diff --git a/src/main.c b/src/main.c index 43170c56..78a0c02d 100644 --- a/src/main.c +++ b/src/main.c @@ -135,6 +135,11 @@ display_usage (void) features++; #endif /* UPSTREAM_SUPPORT */ +#ifdef PACPARSER_SUPPORT + printf (" pacparser support\n"); + features++; +#endif /* PACPARSER_SUPPORT */ + if (0 == features) printf (" None\n"); diff --git a/src/reqs.c b/src/reqs.c index bbdcc74d..2da6c2dd 100644 --- a/src/reqs.c +++ b/src/reqs.c @@ -60,7 +60,11 @@ * enabled. */ #ifdef UPSTREAM_SUPPORT -# define UPSTREAM_CONFIGURED() (config.upstream_list != NULL) +# ifdef PACPARSER_SUPPORT +# define UPSTREAM_CONFIGURED() (config.upstream_list != NULL || config.pac_filename != NULL) +# else +# define UPSTREAM_CONFIGURED() (config.upstream_list != NULL) +# endif # define UPSTREAM_HOST(host) upstream_get(host, config.upstream_list) # define UPSTREAM_IS_HTTP(conn) (conn->upstream_proxy != NULL && conn->upstream_proxy->type == PT_HTTP) #else diff --git a/src/upstream.c b/src/upstream.c index 327b727d..4c74121c 100644 --- a/src/upstream.c +++ b/src/upstream.c @@ -24,11 +24,15 @@ * Routines for handling the list of upstream proxies. */ +#include "string.h" #include "upstream.h" #include "heap.h" #include "log.h" #include "base64.h" #include "basicauth.h" +#ifdef PACPARSER_SUPPORT +#include "pacparser.h" +#endif #ifdef UPSTREAM_SUPPORT const char * @@ -202,6 +206,9 @@ void upstream_add (const char *host, int port, const char *domain, */ struct upstream *upstream_get (char *host, struct upstream *up) { +# ifdef PACPARSER_SUPPORT + return pacparser_get(host); +# endif in_addr_t my_ip = INADDR_NONE; while (up) { @@ -257,4 +264,61 @@ void free_upstream_list (struct upstream *up) } } +#ifdef PACPARSER_SUPPORT + +void pacparser_upstream_init (void) +{ + pacparser_init(); +} + +void pacparser_upstream_load_script (const char *pac_upstream_script) +{ + pacparser_parse_pac(pac_upstream_script); +} + +struct upstream *pacparser_get (const char *host) +{ + char *proxy; + char *colon; + struct upstream *up = NULL; + proxy = pacparser_find_proxy(host, host); + log_message (LOG_INFO, + "Retrieved proxy %s for host %s", proxy, host); + + if (strncmp(proxy, "PROXY ", 6) == 0) { + proxy += 6; + colon = strrchr(proxy, ':'); + if (!colon) { + log_message (LOG_ERR, + "No port in proxy specification from pacparser_find_proxy(). Returning no upstream."); + return NULL; + } + + /* accept a ridiculous memory leak while I'm testing integration * + * with the rest of pac4cli */ + up = (struct upstream *) safemalloc (sizeof (struct upstream)); + if (!up) { + log_message (LOG_ERR, + "Unable to allocate memory in pacparser_get()"); + return NULL; + } + up->type = PT_HTTP; + up->domain = up->ua.user = up->pass = NULL; + up->ip = up->mask = 0; + + up->host = (char *) safemalloc((colon - proxy + 1) * sizeof (char)); + strncpy(up->host, proxy, (colon - proxy) * sizeof(char)); + up->host[colon - proxy] = '\0'; + up->port = atoi(colon + 1); + } + return up; +} + +void pacparser_upstream_cleanup (void) +{ + pacparser_cleanup(); +} + +#endif /* PACPARSER_SUPPORT */ + #endif diff --git a/src/upstream.h b/src/upstream.h index c1127849..cd7ff7b8 100644 --- a/src/upstream.h +++ b/src/upstream.h @@ -61,4 +61,11 @@ extern struct upstream *upstream_get (char *host, struct upstream *up); extern void free_upstream_list (struct upstream *up); #endif /* UPSTREAM_SUPPORT */ +#ifdef PACPARSER_SUPPORT +void pacparser_upstream_init (void); +void pacparser_upstream_load_script (const char *pac_upstream_script); +struct upstream *pacparser_get (const char *host); +void pacparser_upstream_cleanup (void); +#endif + #endif /* _TINYPROXY_UPSTREAM_H_ */