diff options
author | mlaier <mlaier@FreeBSD.org> | 2005-05-03 16:55:20 +0000 |
---|---|---|
committer | mlaier <mlaier@FreeBSD.org> | 2005-05-03 16:55:20 +0000 |
commit | b28479dfe2b344764dddb58a31df37c21423cfde (patch) | |
tree | 7a2c1661f3b801f814c99be7e4339e2b5cfdb86f /contrib/pf/ftp-proxy | |
parent | f9e60af5004dc157f222b733768010aa3d2e98d7 (diff) | |
download | FreeBSD-src-b28479dfe2b344764dddb58a31df37c21423cfde.zip FreeBSD-src-b28479dfe2b344764dddb58a31df37c21423cfde.tar.gz |
Resolve conflicts created during the import of pf 3.7 Some features are
missing and will be implemented in a second step. This is functional as is.
Tested by: freebsd-pf, pfsense.org
Obtained from: OpenBSD
Diffstat (limited to 'contrib/pf/ftp-proxy')
-rw-r--r-- | contrib/pf/ftp-proxy/ftp-proxy.8 | 21 | ||||
-rw-r--r-- | contrib/pf/ftp-proxy/ftp-proxy.c | 80 |
2 files changed, 82 insertions, 19 deletions
diff --git a/contrib/pf/ftp-proxy/ftp-proxy.8 b/contrib/pf/ftp-proxy/ftp-proxy.8 index db043cd..125c5e8 100644 --- a/contrib/pf/ftp-proxy/ftp-proxy.8 +++ b/contrib/pf/ftp-proxy/ftp-proxy.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ftp-proxy.8,v 1.40 2004/03/16 08:50:07 jmc Exp $ +.\" $OpenBSD: ftp-proxy.8,v 1.42 2004/11/19 00:47:23 jmc Exp $ .\" .\" Copyright (c) 1996-2001 .\" Obtuse Systems Corporation, All rights reserved. @@ -37,14 +37,18 @@ .Nd Internet File Transfer Protocol proxy server .Sh SYNOPSIS .Nm ftp-proxy +.Bk -words .Op Fl AnrVw .Op Fl a Ar address .Op Fl D Ar debuglevel .Op Fl g Ar group .Op Fl M Ar maxport .Op Fl m Ar minport +.Op Fl R Ar address[:port] +.Op Fl S Ar address .Op Fl t Ar timeout .Op Fl u Ar user +.Ek .Sh DESCRIPTION .Nm is a proxy for the Internet File Transfer Protocol. @@ -139,12 +143,27 @@ Without this flag, does not require any IP forwarding or NAT beyond the .Em rdr necessary to capture the FTP control connection. +.It Fl R Ar address:[port] +Reverse proxy mode for FTP servers running behind a NAT gateway. +In this mode, no redirection is needed. +The proxy is run from +.Xr inetd 8 +on the port that external clients connect to (usually 21). +Control connections and passive data connections are forwarded +to the server. .It Fl r Use reverse host .Pq reverse DNS lookups for logging and libwrap use. By default, the proxy does not look up hostnames for libwrap or logging purposes. +.It Fl S Ar address +Source address to use for data connections made by the proxy. +Useful when there are multiple addresses (aliases) available +to the proxy. +Clients may expect data connections to have the same source +address as the control connections, and reject or drop other +connections. .It Fl t Ar timeout Specifies a timeout, in seconds. The proxy will exit and close open connections if it sees no data diff --git a/contrib/pf/ftp-proxy/ftp-proxy.c b/contrib/pf/ftp-proxy/ftp-proxy.c index 344ca27..ea4245a 100644 --- a/contrib/pf/ftp-proxy/ftp-proxy.c +++ b/contrib/pf/ftp-proxy/ftp-proxy.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ftp-proxy.c,v 1.35 2004/03/14 21:51:44 dhartmei Exp $ */ +/* $OpenBSD: ftp-proxy.c,v 1.41 2005/03/05 23:11:19 cloder Exp $ */ /* * Copyright (c) 1996-2001 @@ -131,6 +131,8 @@ double xfer_start_time; struct sockaddr_in real_server_sa; struct sockaddr_in client_listen_sa; struct sockaddr_in server_listen_sa; +struct sockaddr_in proxy_sa; +struct in_addr src_addr; int client_listen_socket = -1; /* Only used in PASV mode */ int client_data_socket = -1; /* Connected socket to real client */ @@ -141,13 +143,14 @@ int client_data_bytes, server_data_bytes; int AnonFtpOnly; int Verbose; int NatMode; +int ReverseMode; char ClientName[NI_MAXHOST]; char RealServerName[NI_MAXHOST]; char OurName[NI_MAXHOST]; -char *User = "proxy"; -char *Group; +const char *User = "proxy"; +const char *Group; extern int Debug_Level; extern int Use_Rdns; @@ -175,8 +178,9 @@ static void usage(void) { syslog(LOG_NOTICE, - "usage: %s [-AnrVw] [-a address] [-D debuglevel [-g group]" - " [-M maxport] [-m minport] [-t timeout] [-u user]", __progname); + "usage: %s [-AnrVw] [-a address] [-D debuglevel] [-g group]" + " [-M maxport] [-m minport] [-R address[:port]] [-S address]" + " [-t timeout] [-u user]", __progname); exit(EX_USAGE); } @@ -316,7 +320,7 @@ show_xfer_stats(void) char tbuf[1000]; double delta; size_t len; - int i; + int i = -1; if (!Verbose) return; @@ -343,21 +347,21 @@ show_xfer_stats(void) "data transfer complete (%dh %dm %ds", idelta / (60*60), (idelta % (60*60)) / 60, idelta % 60); - if (i >= len) + if (i == -1 || i >= len) goto logit; len -= i; } else { i = snprintf(tbuf, len, "data transfer complete (%dm %ds", idelta / 60, idelta % 60); - if (i >= len) + if (i == -1 || i >= len) goto logit; len -= i; } } else { i = snprintf(tbuf, len, "data transfer complete (%.1fs", delta); - if (i >= len) + if (i == -1 || i >= len) goto logit; len -= i; } @@ -366,7 +370,7 @@ show_xfer_stats(void) i = snprintf(&tbuf[strlen(tbuf)], len, ", %d bytes to server) (%.1fKB/s", client_data_bytes, (client_data_bytes / delta) / (double)1024); - if (i >= len) + if (i == -1 || i >= len) goto logit; len -= i; } @@ -374,20 +378,21 @@ show_xfer_stats(void) i = snprintf(&tbuf[strlen(tbuf)], len, ", %d bytes to client) (%.1fKB/s", server_data_bytes, (server_data_bytes / delta) / (double)1024); - if (i >= len) + if (i == -1 || i >= len) goto logit; len -= i; } strlcat(tbuf, ")", sizeof(tbuf)); logit: - syslog(LOG_INFO, "%s", tbuf); + if (i != -1) + syslog(LOG_INFO, "%s", tbuf); } void log_control_command (char *cmd, int client) { /* log an ftp control command or reply */ - char *logstring; + const char *logstring; int level = LOG_DEBUG; if (!Verbose) @@ -540,7 +545,7 @@ connect_port_backchannel(void) * getting one bound to port 20 - This is deliberately * not RFC compliant. */ - bzero(&listen_sa.sin_addr, sizeof(struct in_addr)); + bcopy(&src_addr, &listen_sa.sin_addr, sizeof(struct in_addr)); client_data_socket = get_backchannel_socket(SOCK_STREAM, min_port, max_port, -1, 1, &listen_sa); if (client_data_socket < 0) { @@ -558,7 +563,7 @@ connect_port_backchannel(void) salen = 1; listen_sa.sin_family = AF_INET; - bzero(&listen_sa.sin_addr, sizeof(struct in_addr)); + bcopy(&src_addr, &listen_sa.sin_addr, sizeof(struct in_addr)); listen_sa.sin_port = htons(20); if (setsockopt(client_data_socket, SOL_SOCKET, SO_REUSEADDR, @@ -928,7 +933,10 @@ do_server_reply(struct csiob *server, struct csiob *client) new_dataconn(0); connection_mode = PASV_MODE; - iap = &(server->sa.sin_addr); + if (ReverseMode) + iap = &(proxy_sa.sin_addr); + else + iap = &(server->sa.sin_addr); debuglog(1, "we want client to use %s:%u", inet_ntoa(*iap), htons(client_listen_sa.sin_port)); @@ -976,7 +984,7 @@ main(int argc, char *argv[]) int use_tcpwrapper = 0; #endif /* LIBWRAP */ - while ((ch = getopt(argc, argv, "a:D:g:m:M:t:u:AnVwr")) != -1) { + while ((ch = getopt(argc, argv, "a:D:g:m:M:R:S:t:u:AnVwr")) != -1) { char *p; switch (ch) { case 'a': @@ -1019,6 +1027,41 @@ main(int argc, char *argv[]) case 'r': Use_Rdns = 1; /* look up hostnames */ break; + case 'R': { + char *s, *t; + + if (!*optarg) + usage(); + if ((s = strdup(optarg)) == NULL) { + syslog (LOG_NOTICE, + "Insufficient memory (malloc failed)"); + exit(EX_UNAVAILABLE); + } + memset(&real_server_sa, 0, sizeof(real_server_sa)); + real_server_sa.sin_len = sizeof(struct sockaddr_in); + real_server_sa.sin_family = AF_INET; + t = strchr(s, ':'); + if (t == NULL) + real_server_sa.sin_port = htons(21); + else { + long port = strtol(t + 1, &p, 10); + + if (*p || port <= 0 || port > 65535) + usage(); + real_server_sa.sin_port = htons(port); + *t = 0; + } + real_server_sa.sin_addr.s_addr = inet_addr(s); + if (real_server_sa.sin_addr.s_addr == INADDR_NONE) + usage(); + free(s); + ReverseMode = 1; + break; + } + case 'S': + if (!inet_aton(optarg, &src_addr)) + usage(); + break; case 't': timeout_seconds = strtol(optarg, &p, 10); if (!*optarg || *p) @@ -1054,7 +1097,8 @@ main(int argc, char *argv[]) memset(&client_iob, 0, sizeof(client_iob)); memset(&server_iob, 0, sizeof(server_iob)); - if (get_proxy_env(0, &real_server_sa, &client_iob.sa) == -1) + if (get_proxy_env(0, &real_server_sa, &client_iob.sa, + &proxy_sa) == -1) exit(EX_PROTOCOL); /* |