Many sites on the net today choose to block most incoming TCP sessions
while allowing outgoing connections as a compromise between utility and
security. The trouble with this is that blocking incoming connections
kills traditional ftp client programs since they use the "port" command
to tell the server where to connect to send the file. The server then
opens a connection to an effectively arbitrarily chosen socket number.
Fortunately there is an alternative to this behavior that allows the
client to open the data socket, which allows you to have the firewall
and ftp too. This alternate paradigm basically emulates proxy mode
transfers. The client sends a PASV command to the server, then opens a
data socket to the indicated address, and finally sends the transfer
command.
The only trouble with this idea is that it breaks down when the server
site has a similarly paranoid administrator and has blocked arbitrary
incoming connections. Because of this, the passive behavior should be
user-selectable. So this patch adds a 'passive' command that toggles the
behavior (defaulting to on). If you find that passive transfers aren't
working, just type 'passive' and it will revert to the traditional
"port" commands (you can of course use the "sendport" command to change
this).
Credit for the idea goes to Steve Bellovin. Many thanks for the start,
Steve.
Obtain the source to the ftp client in the BSD sources (uunet has it),
unpack it and apply this patch.
If you're building for SunOS 4.1.x, you will also want to add
typedef void (*sig_t)();
to ftp_var.h and replace the include of <paths.h> with a
#define _PATH_BSHELL "/bin/sh" in pathnames.h to make the program
compile properly.
*** ./cmds.c Sun Oct 10 09:17:00 1993
--- ../cmds.c Sat Oct 9 05:21:10 1993
***************
*** 2133,2135 ****
--- 2133,2150 ----
printf("Local file \"%s\" is newer than remote file \"%s\"\n",
argv[1], argv[2]);
}
+
+ #ifndef NO_PASSIVE_MODE
+ /*
+ * Start up passive mode interaction
+ */
+
+ /*VARARGS*/
+ setpassive()
+ {
+
+ passivemode = !passivemode;
+ printf("Passive mode %s.\n", onoff(passivemode));
+ code = passivemode;
+ }
+ #endif
*** ./cmdtab.c Sun Oct 10 09:17:04 1993
--- ../cmdtab.c Sat Oct 9 05:24:57 1993
***************
*** 54,59 ****
--- 54,62 ----
int setsunique(), setrunique(), cdup(), macdef(), domacro();
int sizecmd(), modtime(), newer(), rmtstatus();
int do_chmod(), do_umask(), idle();
+ #ifndef NO_PASSIVE_MODE
+ int setpassive();
+ #endif
char accounthelp[] = "send account command to remote server";
char appendhelp[] = "append to a file";
***************
*** 120,125 ****
--- 123,131 ----
char umaskhelp[] = "get (set) umask on remote side";
char userhelp[] = "send new user information";
char verbosehelp[] = "toggle verbose mode";
+ #ifndef NO_PASSIVE_MODE
+ char setpassivehelp[] = "enter passive transfer mode";
+ #endif
struct cmd cmdtab[] = {
{ "!", shellhelp, 0, 0, 0, shell },
***************
*** 164,169 ****
--- 170,178 ----
{ "ntrans", ntranshelp, 0, 0, 1, setntrans },
{ "open", connecthelp, 0, 0, 1, setpeer },
{ "prompt", prompthelp, 0, 0, 0, setprompt },
+ #ifndef NO_PASSIVE_MODE
+ { "passive", setpassivehelp, 0, 0, 0, setpassive },
+ #endif
{ "proxy", proxyhelp, 0, 0, 1, doproxy },
{ "sendport", porthelp, 0, 0, 0, setport },
{ "put", sendhelp, 1, 1, 1, put },
*** ./ftp.c Sun Oct 10 09:17:29 1993
--- ../ftp.c Sat Oct 9 05:44:04 1993
***************
*** 1002,1008 ****
--- 1002,1057 ----
register char *p, *a;
int result, len, tmpno = 0;
int on = 1;
+ #ifndef NO_PASSIVE_MODE
+ int a1,a2,a3,a4,p1,p2;
+ if (passivemode) {
+ data = socket(AF_INET, SOCK_STREAM, 0);
+ if (data < 0) {
+ perror("ftp: socket");
+ return(1);
+ }
+ if (options & SO_DEBUG &&
+ setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof (on)) < 0)
+ perror("ftp: setsockopt (ignored)");
+ if (command("PASV") != COMPLETE) {
+ printf("Passive mode refused.\n");
+ return(1);
+ }
+
+ /*
+ * What we've got at this point is a string of comma separated
+ * one-byte unsigned integer values, separated by commas.
+ * The first four are the an IP address. The fifth is the MSB
+ * of the port number, the sixth is the LSB. From that we'll
+ * prepare a sockaddr_in.
+ */
+
+ if (sscanf(pasv,"%d,%d,%d,%d,%d,%d",&a1,&a2,&a3,&a4,&p1,&p2) != 6) {
+ printf("Passive mode address scan failure. Shouldn't happen!\n");
+ return(1);
+ };
+
+ data_addr.sin_family = AF_INET;
+ data_addr.sin_addr.S_un.S_un_b.s_b1 = a1;
+ data_addr.sin_addr.S_un.S_un_b.s_b2 = a2;
+ data_addr.sin_addr.S_un.S_un_b.s_b3 = a3;
+ data_addr.sin_addr.S_un.S_un_b.s_b4 = a4;
+ data_addr.sin_port = (p1<<8)|p2;
+
+ if (connect(data, (struct sockaddr *) &data_addr, sizeof(data_addr))<0) {
+ perror("ftp: connect");
+ return(1);
+ }
+ #ifdef IP_TOS
+ on = IPTOS_THROUGHPUT;
+ if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)) < 0)
+ perror("ftp: setsockopt TOS (ignored)");
+ #endif
+ return(0);
+ }
+ #endif
+
noport:
data_addr = myctladdr;
if (sendport)
***************
*** 1072,1077 ****
--- 1121,1130 ----
struct sockaddr_in from;
int s, fromlen = sizeof (from), tos;
+ #ifndef NO_PASSIVE_MODE
+ if (passivemode)
+ return (fdopen(data, lmode));
+ #endif
s = accept(data, (struct sockaddr *) &from, &fromlen);
if (s < 0) {
perror("ftp: accept");
*** ./ftp_var.h Sun Oct 10 09:17:33 1993
--- ../ftp_var.h Sat Oct 9 04:50:51 1993
***************
*** 61,66 ****
--- 63,71 ----
int code; /* return/reply code for ftp command */
int crflag; /* if 1, strip car. rets. on ascii gets */
char pasv[64]; /* passive port for proxy data connection */
+ #ifndef NO_PASSIVE_MODE
+ int passivemode; /* passive mode enabled */
+ #endif
char *altarg; /* argv[1] with no shell-like preprocessing */
char ntin[17]; /* input translation table */
char ntout[17]; /* output translation table */
*** ./main.c Sun Oct 10 09:17:45 1993
--- ../main.c Sat Oct 9 05:42:13 1993
***************
*** 121,126 ****
--- 121,129 ----
verbose++;
cpend = 0; /* no pending replies */
proxy = 0; /* proxy not active */
+ #ifndef NO_PASSIVE_MODE
+ passivemode = 1; /* passive mode active */
+ #endif
crflag = 1; /* strip c.r. on ascii gets */
sendport = -1; /* not using ports */
/*
Follow-Ups:
|
|