From 5ea289d82ea412b59bbabd1ddfff70d3d5f1ecb2 Mon Sep 17 00:00:00 2001 From: Robert James Kaes Date: Sun, 8 Jun 2008 18:50:23 -0400 Subject: Moved transparent proxy code into its own file Extracted the transparent proxy logic from reqs.c and placed it into a separate file. Signed-off-by: Robert James Kaes --- configure.ac | 1 + src/Makefile.am | 3 +- src/reqs.c | 122 ++++-------------------------------------------- src/reqs.h | 22 +++++++++ src/transparent-proxy.c | 121 +++++++++++++++++++++++++++++++++++++++++++++++ src/transparent-proxy.h | 39 ++++++++++++++++ 6 files changed, 194 insertions(+), 114 deletions(-) create mode 100644 src/transparent-proxy.c create mode 100644 src/transparent-proxy.h diff --git a/configure.ac b/configure.ac index 8e8f8ba..5971bc0 100644 --- a/configure.ac +++ b/configure.ac @@ -141,6 +141,7 @@ TP_ARG_ENABLE(transparent, [Enable transparent proxying code (default is NO)], no) if test x"$transparent_enabled" = x"yes"; then + ADDITIONAL_OBJECTS="$ADDITIONAL_OBJECTS transparent-proxy.o" AC_DEFINE(TRANSPARENT_PROXY) fi diff --git a/src/Makefile.am b/src/Makefile.am index 3910e33..4b616e0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -41,6 +41,7 @@ tinyproxy_SOURCES = \ vector.c vector.h EXTRA_tinyproxy_SOURCES = filter.c filter.h \ - reverse-proxy.c reverse-proxy.h + reverse-proxy.c reverse-proxy.h \ + transparent-proxy.c transparent-proxy.h tinyproxy_DEPENDENCIES = @ADDITIONAL_OBJECTS@ tinyproxy_LDADD = @ADDITIONAL_OBJECTS@ diff --git a/src/reqs.c b/src/reqs.c index 5c5ff77..8d8cbe3 100644 --- a/src/reqs.c +++ b/src/reqs.c @@ -44,17 +44,13 @@ #include "utils.h" #include "vector.h" #include "reverse-proxy.h" +#include "transparent-proxy.h" /* * Maximum length of a HTTP line */ #define HTTP_LINE_LENGTH (MAXBUFFSIZE / 6) -/* - * Port constants for HTTP (80) and SSL (443) - */ -#define HTTP_PORT 80 -#define HTTP_PORT_SSL 443 /* * Macro to help test if the Upstream proxy supported is compiled in and @@ -79,18 +75,6 @@ */ static vector_t ports_allowed_by_connect = NULL; -/* - * This structure holds the information pulled from a URL request. - */ -struct request_s { - char *method; - char *protocol; - - char *host; - uint16_t port; - - char *path; -}; /* * Now, this routine adds a "port" to the list. It also creates the list if @@ -316,28 +300,6 @@ extract_ssl_url(const char *url, struct request_s *request) return 0; } -#ifdef TRANSPARENT_PROXY -/* - * Build a URL from parts. - */ -static int -build_url(char **url, const char *host, int port, const char *path) -{ - int len; - - assert(url != NULL); - assert(host != NULL); - assert(port > 0 && port < 32768); - assert(path != NULL); - - len = strlen(host) + strlen(path) + 14; - *url = safemalloc(len); - if (*url == NULL) - return -1; - - return snprintf(*url, len, "http://%s:%d%s", host, port, path); -} -#endif /* TRANSPARENT_PROXY */ #ifdef UPSTREAM_SUPPORT /* @@ -692,88 +654,22 @@ process_request(struct conn_s *connptr, hashmap_t hashofheaders) connptr->connect_method = TRUE; } else { #ifdef TRANSPARENT_PROXY - /* - * This section of code is used for the transparent proxy - * option. You will need to configure your firewall to - * redirect all connections for HTTP traffic to tinyproxy - * for this to work properly. - * - * This code was written by Petr Lampa - */ - int length; - char *data; - - length = - hashmap_entry_by_key(hashofheaders, "host", (void **)&data); - if (length <= 0) { - struct sockaddr_in dest_addr; - - if (getsockname - (connptr->client_fd, (struct sockaddr *)&dest_addr, - &length) < 0) { - log_message(LOG_ERR, - "process_request: cannot get destination IP for %d", - connptr->client_fd); - indicate_http_error(connptr, 400, "Bad Request", - "detail", - "Unknown destination", - "url", url, NULL); - safefree(url); - free_request_struct(request); - return NULL; - } - request->host = safemalloc(17); - strcpy(request->host, inet_ntoa(dest_addr.sin_addr)); - request->port = ntohs(dest_addr.sin_port); - request->path = safemalloc(strlen(url) + 1); - strcpy(request->path, url); - safefree(url); - build_url(&url, request->host, request->port, - request->path); - log_message(LOG_INFO, - "process_request: trans IP %s %s for %d", - request->method, url, connptr->client_fd); - } else { - request->host = safemalloc(length + 1); - if (sscanf - (data, "%[^:]:%hu", request->host, - &request->port) != 2) { - strcpy(request->host, data); - request->port = HTTP_PORT; - } - request->path = safemalloc(strlen(url) + 1); - strcpy(request->path, url); - safefree(url); - build_url(&url, request->host, request->port, - request->path); - log_message(LOG_INFO, - "process_request: trans Host %s %s for %d", - request->method, url, connptr->client_fd); - } - if (config.ipAddr && strcmp(request->host, config.ipAddr) == 0) { - log_message(LOG_ERR, - "process_request: destination IP is localhost %d", - connptr->client_fd); - indicate_http_error(connptr, 400, "Bad Request", - "detail", - "You tried to connect to the machine the proxy is running on", - "url", url, NULL); + if (!do_transparent_proxy(connptr, hashofheaders, request, &config, url)) { safefree(url); free_request_struct(request); return NULL; } #else - log_message(LOG_ERR, - "process_request: Unknown URL type on file descriptor %d", - connptr->client_fd); - indicate_http_error(connptr, 400, "Bad Request", - "detail", "Unknown URL type", - "url", url, NULL); - + indicate_http_error(connptr, 501, "Not Implemented", + "detail", "Unknown method or unsupported protocol.", + "url", url, NULL); + log_message(LOG_INFO, + "Unknown method (%s) or protocol (%s)", + request->method, url); safefree(url); free_request_struct(request); - return NULL; + #endif } diff --git a/src/reqs.h b/src/reqs.h index 2748bab..de8730e 100644 --- a/src/reqs.h +++ b/src/reqs.h @@ -22,6 +22,28 @@ #ifndef _TINYPROXY_REQS_H_ #define _TINYPROXY_REQS_H_ +#include "common.h" + + +/* + * Port constants for HTTP (80) and SSL (443) + */ +#define HTTP_PORT 80 +#define HTTP_PORT_SSL 443 + +/* + * This structure holds the information pulled from a URL request. + */ +struct request_s { + char *method; + char *protocol; + + char *host; + uint16_t port; + + char *path; +}; + extern void handle_connection(int fd); extern void add_connect_port_allowed(int port); extern void upstream_add(const char *host, int port, const char *domain); diff --git a/src/transparent-proxy.c b/src/transparent-proxy.c new file mode 100644 index 0000000..5bffa31 --- /dev/null +++ b/src/transparent-proxy.c @@ -0,0 +1,121 @@ +/* tinyproxy - A fast light-weight HTTP proxy + * Copyright (C) 2002 Petr Lampa + * Copyright (C) 2008 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. + */ + +/* + * This section of code is used for the transparent proxy option. You will + * need to configure your firewall to redirect all connections for HTTP + * traffic to tinyproxy for this to work properly. + */ + +#include "tinyproxy.h" + +#include "transparent-proxy.h" +#include "conns.h" +#include "heap.h" +#include "html-error.h" +#include "log.h" +#include "reqs.h" + +/* + * Build a URL from parts. + */ +static int +build_url(char **url, const char *host, int port, const char *path) +{ + int len; + + assert(url != NULL); + assert(host != NULL); + assert(port > 0 && port < 32768); + assert(path != NULL); + + len = strlen(host) + strlen(path) + 14; + *url = safemalloc(len); + if (*url == NULL) + return -1; + + return snprintf(*url, len, "http://%s:%d%s", host, port, path); +} + + +int +do_transparent_proxy(struct conn_s *connptr, hashmap_t hashofheaders, + struct request_s *request, struct config_s *conf, char *url) +{ + socklen_t length; + char *data; + + length = + hashmap_entry_by_key(hashofheaders, "host", (void **)&data); + if (length <= 0) { + struct sockaddr_in dest_addr; + + if (getsockname + (connptr->client_fd, (struct sockaddr *)&dest_addr, + &length) < 0) { + log_message(LOG_ERR, + "process_request: cannot get destination IP for %d", + connptr->client_fd); + indicate_http_error(connptr, 400, "Bad Request", + "detail", + "Unknown destination", + "url", url, NULL); + return 0; + } + request->host = safemalloc(17); + strcpy(request->host, inet_ntoa(dest_addr.sin_addr)); + request->port = ntohs(dest_addr.sin_port); + request->path = safemalloc(strlen(url) + 1); + strcpy(request->path, url); + safefree(url); + build_url(&url, request->host, request->port, + request->path); + log_message(LOG_INFO, + "process_request: trans IP %s %s for %d", + request->method, url, connptr->client_fd); + } else { + request->host = safemalloc(length + 1); + if (sscanf + (data, "%[^:]:%hu", request->host, + &request->port) != 2) { + strcpy(request->host, data); + request->port = HTTP_PORT; + } + request->path = safemalloc(strlen(url) + 1); + strcpy(request->path, url); + safefree(url); + build_url(&url, request->host, request->port, + request->path); + log_message(LOG_INFO, + "process_request: trans Host %s %s for %d", + request->method, url, connptr->client_fd); + } + if (conf->ipAddr && strcmp(request->host, conf->ipAddr) == 0) { + log_message(LOG_ERR, + "process_request: destination IP is localhost %d", + connptr->client_fd); + indicate_http_error(connptr, 400, "Bad Request", + "detail", + "You tried to connect to the machine the proxy is running on", + "url", url, NULL); + return 0; + } + + return 1; +} diff --git a/src/transparent-proxy.h b/src/transparent-proxy.h new file mode 100644 index 0000000..37cc54d --- /dev/null +++ b/src/transparent-proxy.h @@ -0,0 +1,39 @@ +/* tinyproxy - A fast light-weight HTTP proxy + * Copyright (C) 2008 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 'transparent-proxy.c' for detailed information. */ + +#ifndef TINYPROXY_TRANSPARENT_PROXY_H +#define TINYPROXY_TRANSPARENT_PROXY_H + +#include "common.h" + +#ifdef TRANSPARENT_PROXY + +#include "conns.h" +#include "hashmap.h" +#include "reqs.h" + +extern int do_transparent_proxy(struct conn_s *connptr, + hashmap_t hashofheaders, struct request_s *request, + struct config_s *config, char *url); + + +#endif + +#endif -- cgit v1.2.3