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 <rjk@wormbytes.ca>
This commit is contained in:
Robert James Kaes 2008-06-08 18:50:23 -04:00 committed by Mukund Sivaraman
parent 445e4cb09c
commit 5ea289d82e
6 changed files with 194 additions and 114 deletions

View File

@ -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

View File

@ -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@

View File

@ -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 <lampa@fit.vutbr.cz>
*/
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
}

View File

@ -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);

121
src/transparent-proxy.c Normal file
View File

@ -0,0 +1,121 @@
/* tinyproxy - A fast light-weight HTTP proxy
* Copyright (C) 2002 Petr Lampa <lampa@fit.vutbr.cz>
* Copyright (C) 2008 Robert James Kaes <rjk@wormbytes.ca>
*
* 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;
}

39
src/transparent-proxy.h Normal file
View File

@ -0,0 +1,39 @@
/* tinyproxy - A fast light-weight HTTP proxy
* Copyright (C) 2008 Robert James Kaes <rjk@wormbytes.ca>
*
* 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