Subject: Patch for transparent ftp proxy

From: René Antonio Araos Carvacho <[email-masked]>
Date: Sun, 25 Feb 2001 22:53:38 -0300

Hi

     This is a patch useful for a ftp proxy who is behind a firewall, this
makes connections like ftp, (example, ftp = 21 then ftp-data = 20, ftp =
1021, ftp-data=1020).

     Please send me comments, if you find a bug in this or not   :-)

greetings

René Araos

##begin diff file
diff -u --recursive --new-file fwtk/ftp-gw/ftp-gw.c fwtkrene/ftp-gw/ftp-gw.c

--- fwtk/ftp-gw/ftp-gw.c Thu Feb 5 21:05:43 1998

+++ fwtkrene/ftp-gw/ftp-gw.c Fri Feb 23 18:47:44 2001

@@ -66,6 +66,7 @@

static int outgoing = -1; /* fd for outgoing PORT data */

static int incoming = -1; /* fd for outgoing PORT data */

static struct sockaddr_in clntport;

+static struct sockaddr_in original;

static char **saveresp = (char **)0;

static int saveresps = 0;

static char riaddr[512];

@@ -173,6 +174,7 @@

char xuf[1024];

char huf[512];

char *passuser = (char *)0; /* passed user as av */

+ int addrlen;

#ifndef LOG_DAEMON

openlog("ftp-gw",LOG_PID);

@@ -227,6 +229,19 @@

exit(1);

}

+/* mod */

+

+ addrlen = sizeof(addrlen);

+ if (getsockname(0, (struct sockaddr *)&original, &addrlen) < 0) {

+ syslog(LOG_ERR, "getsockname (%s): %m",av[0]);

+ exit(1);

+ }

+ original.sin_port = htons(ntohs(original.sin_port) - 1);

+/*

+ original.sin_port = htons(0x14);

+*/

+

+/* fin mod */

if((cf = cfg_get("groupid",confp)) != (Cfg *)0) {

@@ -415,6 +430,7 @@

if(incoming != -1 && FD_ISSET(incoming,&rdy)) {

if(copyin())

break;

+ close(incoming);

}

}

leave:

@@ -1035,7 +1051,6 @@

if(porttoaddr(av[1],&clntport))

return(sayn(0,nadr,sizeof(nadr)-1));

-

/* paranoid: check that we are really PORTing to the client */

x = sizeof(r);

if(getpeername(0,(struct sockaddr *)&r,&x) < 0)

@@ -1313,6 +1328,8 @@

/* call back to the client on the address they gave as PORT */

callback()

{

+ int data, tries;

+ int on=1;

/* if we haven't gotten a valid PORT scrub the connection */

if((outgoing = accept(boundport,(struct sockaddr *)0,(int *)0)) < 0)

goto bomb;

@@ -1324,6 +1341,21 @@

if((incoming = socket(AF_INET,SOCK_STREAM,0)) < 0)

goto bomb;

+/*inicio mod*/

+ if (setsockopt(incoming, SOL_SOCKET, SO_REUSEADDR,

+ (char *) &on, sizeof(on)) < 0)

+ goto bomb;

+ for (tries = 1; ; tries++) {

+ if (bind(incoming, (struct sockaddr *)&original,

+ sizeof(original)) >= 0)

+ break;

+ if (errno != EADDRINUSE || tries > 10)

+ goto bomb;

+ sleep(tries);

+ }

+

+/*fin mod*/

+

if(connect(incoming,(struct sockaddr *)&clntport,sizeof(clntport)) < 0)

goto bomb;

##end diff file