summaryrefslogtreecommitdiffstats
path: root/contrib/pf/ftp-proxy
diff options
context:
space:
mode:
authormlaier <mlaier@FreeBSD.org>2005-05-03 16:47:37 +0000
committermlaier <mlaier@FreeBSD.org>2005-05-03 16:47:37 +0000
commit511d1c13c361b4534ed4c6f973fd891d95055cab (patch)
treebab48c44c0d19fa874cf07baf703335409f81c2b /contrib/pf/ftp-proxy
parent51d3d6ad22798e39cfde335297ece533ba5b6fb6 (diff)
downloadFreeBSD-src-511d1c13c361b4534ed4c6f973fd891d95055cab.zip
FreeBSD-src-511d1c13c361b4534ed4c6f973fd891d95055cab.tar.gz
Import pf userland from OpenBSD 3.7 (OPENBSD_3_7 as of today)
Diffstat (limited to 'contrib/pf/ftp-proxy')
-rw-r--r--contrib/pf/ftp-proxy/ftp-proxy.821
-rw-r--r--contrib/pf/ftp-proxy/ftp-proxy.c80
-rw-r--r--contrib/pf/ftp-proxy/getline.c8
-rw-r--r--contrib/pf/ftp-proxy/util.c17
-rw-r--r--contrib/pf/ftp-proxy/util.h6
5 files changed, 100 insertions, 32 deletions
diff --git a/contrib/pf/ftp-proxy/ftp-proxy.8 b/contrib/pf/ftp-proxy/ftp-proxy.8
index e68bdde..e128136 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.
@@ -35,14 +35,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.
@@ -137,12 +141,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 18bc0a6..dd0c654 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
@@ -128,6 +128,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 */
@@ -138,13 +140,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;
@@ -172,8 +175,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);
}
@@ -313,7 +317,7 @@ show_xfer_stats(void)
char tbuf[1000];
double delta;
size_t len;
- int i;
+ int i = -1;
if (!Verbose)
return;
@@ -340,21 +344,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;
}
@@ -363,7 +367,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;
}
@@ -371,20 +375,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)
@@ -537,7 +542,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) {
@@ -555,7 +560,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,
@@ -925,7 +930,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));
@@ -973,7 +981,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':
@@ -1016,6 +1024,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)
@@ -1051,7 +1094,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);
/*
diff --git a/contrib/pf/ftp-proxy/getline.c b/contrib/pf/ftp-proxy/getline.c
index 2be3883..97ffd48 100644
--- a/contrib/pf/ftp-proxy/getline.c
+++ b/contrib/pf/ftp-proxy/getline.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: getline.c,v 1.15 2003/06/28 01:04:57 deraadt Exp $ */
+/* $OpenBSD: getline.c,v 1.16 2004/09/16 04:50:51 deraadt Exp $ */
/*
* Copyright (c) 1985, 1988 Regents of the University of California.
@@ -96,7 +96,7 @@ refill_buffer(struct csiob *iobp)
/* don't do tiny reads, grow first if we need to */
rqlen = iobp->io_buffer_size - iobp->io_buffer_len;
if (rqlen <= 128) {
- char *tmp;
+ unsigned char *tmp;
iobp->io_buffer_size += 128;
tmp = realloc(iobp->io_buffer, iobp->io_buffer_size);
@@ -152,7 +152,7 @@ telnet_getline(struct csiob *iobp, struct csiob *telnet_passthrough)
{
unsigned char ch;
int ix;
- char tbuf[100];
+ unsigned char tbuf[100];
iobp->line_buffer[0] = '\0';
@@ -236,7 +236,7 @@ telnet_getline(struct csiob *iobp, struct csiob *telnet_passthrough)
* nasty.
*/
if (ix - iobp->next_byte > iobp->line_buffer_size - 5) {
- char *tmp;
+ unsigned char *tmp;
iobp->line_buffer_size = 256 + ix - iobp->next_byte;
tmp = realloc(iobp->line_buffer,
diff --git a/contrib/pf/ftp-proxy/util.c b/contrib/pf/ftp-proxy/util.c
index 17a88ca..61c9f1f 100644
--- a/contrib/pf/ftp-proxy/util.c
+++ b/contrib/pf/ftp-proxy/util.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: util.c,v 1.18 2004/01/22 16:10:30 beck Exp $ */
+/* $OpenBSD: util.c,v 1.19 2004/07/06 19:49:11 dhartmei Exp $ */
/*
* Copyright (c) 1996-2001
@@ -56,6 +56,8 @@
#include "util.h"
+extern int ReverseMode;
+
int Debug_Level;
int Use_Rdns;
in_addr_t Bind_Addr = INADDR_NONE;
@@ -75,14 +77,14 @@ debuglog(int debug_level, const char *fmt, ...)
int
get_proxy_env(int connected_fd, struct sockaddr_in *real_server_sa_ptr,
- struct sockaddr_in *client_sa_ptr)
+ struct sockaddr_in *client_sa_ptr, struct sockaddr_in *proxy_sa_ptr)
{
struct pfioc_natlook natlook;
socklen_t slen;
int fd;
- slen = sizeof(*real_server_sa_ptr);
- if (getsockname(connected_fd, (struct sockaddr *)real_server_sa_ptr,
+ slen = sizeof(*proxy_sa_ptr);
+ if (getsockname(connected_fd, (struct sockaddr *)proxy_sa_ptr,
&slen) != 0) {
syslog(LOG_ERR, "getsockname() failed (%m)");
return(-1);
@@ -94,6 +96,9 @@ get_proxy_env(int connected_fd, struct sockaddr_in *real_server_sa_ptr,
return(-1);
}
+ if (ReverseMode)
+ return(0);
+
/*
* Build up the pf natlook structure.
* Just for IPv4 right now
@@ -101,10 +106,10 @@ get_proxy_env(int connected_fd, struct sockaddr_in *real_server_sa_ptr,
memset((void *)&natlook, 0, sizeof(natlook));
natlook.af = AF_INET;
natlook.saddr.addr32[0] = client_sa_ptr->sin_addr.s_addr;
- natlook.daddr.addr32[0] = real_server_sa_ptr->sin_addr.s_addr;
+ natlook.daddr.addr32[0] = proxy_sa_ptr->sin_addr.s_addr;
natlook.proto = IPPROTO_TCP;
natlook.sport = client_sa_ptr->sin_port;
- natlook.dport = real_server_sa_ptr->sin_port;
+ natlook.dport = proxy_sa_ptr->sin_port;
natlook.direction = PF_OUT;
/*
diff --git a/contrib/pf/ftp-proxy/util.h b/contrib/pf/ftp-proxy/util.h
index 597cd18..ce1e915 100644
--- a/contrib/pf/ftp-proxy/util.h
+++ b/contrib/pf/ftp-proxy/util.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: util.h,v 1.3 2002/05/23 10:22:14 deraadt Exp $ */
+/* $OpenBSD: util.h,v 1.5 2005/02/24 15:49:08 dhartmei Exp $ */
/*
* Copyright (c) 1996-2001
@@ -46,7 +46,7 @@ struct csiob {
int line_buffer_size, io_buffer_size, io_buffer_len, next_byte;
unsigned char *io_buffer, *line_buffer;
struct sockaddr_in sa, real_sa;
- char *who;
+ const char *who;
char alive, got_eof, data_available;
int send_oob_flags;
};
@@ -55,7 +55,7 @@ extern int telnet_getline(struct csiob *iobp,
struct csiob *telnet_passthrough);
extern int get_proxy_env(int fd, struct sockaddr_in *server_sa_ptr,
- struct sockaddr_in *client_sa_ptr);
+ struct sockaddr_in *client_sa_ptr, struct sockaddr_in *proxy_sa_ptr);
extern int get_backchannel_socket(int type, int min_port, int max_port,
int start_port, int direction, struct sockaddr_in *sap);
OpenPOWER on IntegriCloud