--- ftp-proxy.c.orig Tue Mar 12 16:49:27 2002 +++ ftp-proxy.c Tue Mar 12 17:14:45 2002 @@ -126,6 +126,7 @@ struct sockaddr_in real_server_sa; struct sockaddr_in client_listen_sa; struct sockaddr_in server_listen_sa; +struct sockaddr_in proxy_server_sa; int client_listen_socket = -1; /* Only used in PASV mode */ int client_data_socket = -1; /* Connected socket to real client */ @@ -136,6 +137,7 @@ int AnonFtpOnly; int Verbose; int NatMode; +int ReverseMode; char ClientName[NI_MAXHOST]; char RealServerName[NI_MAXHOST]; @@ -924,7 +926,10 @@ new_dataconn(0); connection_mode = PASV_MODE; - iap = &(server->sa.sin_addr); + if(ReverseMode) + iap = &(proxy_server_sa.sin_addr); + else + iap = &(server->sa.sin_addr); debuglog(1, "we want client to use %s:%u\n", inet_ntoa(*iap), htons(client_listen_sa.sin_port)); @@ -968,8 +973,9 @@ long timeout_seconds = 0; struct timeval tv; - while ((ch = getopt(argc, argv, "D:g:m:M:t:u:AnVwr")) != -1) { - char *p; + while ((ch = getopt(argc, argv, "D:g:m:M:t:u:R:AnVwr")) != -1) { + char *p, *s, *t; + unsigned long port; switch (ch) { case 'A': AnonFtpOnly = 1; /* restrict to anon usernames only */ @@ -1016,6 +1022,33 @@ case 'w': use_tcpwrapper = 1; /* do the libwrap thing */ break; + case 'R': + if(!*optarg) + usage(); + s = strdup(optarg); + if(s==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(real_server_sa); + real_server_sa.sin_family = AF_INET; + t = strchr(s,':'); + if(t){ + port = strtoul(t+1,&p,10); + if(*p || port > 65535) + usage(); + real_server_sa.sin_port = htons(port); + *t = '\0'; + } else { + real_server_sa.sin_port = htons(21); + } + 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; default: usage(); /* NOTREACHED */ @@ -1035,7 +1068,7 @@ 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_server_sa) == -1) exit(EX_PROTOCOL); /* --- util.c.orig Tue Mar 12 16:49:39 2002 +++ util.c Tue Mar 12 17:06:31 2002 @@ -61,6 +61,8 @@ int Debug_Level; int Use_Rdns; +extern int ReverseMode; + void debuglog(int debug_level, const char *fmt, ...) { @@ -74,18 +76,28 @@ 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_server_sa_ptr) { struct pfioc_natlook natlook; char *client; int slen, fd; - slen = sizeof(*real_server_sa_ptr); - if (getsockname(connected_fd, (struct sockaddr *)real_server_sa_ptr, - &slen) != 0) { - syslog(LOG_ERR, "getsockname failed (%m)"); - return(-1); + if(ReverseMode){ + slen = sizeof(*proxy_server_sa_ptr); + if (getsockname(connected_fd, (struct sockaddr *)proxy_server_sa_ptr, + &slen) != 0) { + syslog(LOG_ERR, "getsockname failed (%m)"); + return(-1); + } + } else { + slen = sizeof(*real_server_sa_ptr); + if (getsockname(connected_fd, (struct sockaddr *)real_server_sa_ptr, + &slen) != 0) { + syslog(LOG_ERR, "getsockname failed (%m)"); + return(-1); + } } + slen = sizeof(*client_sa_ptr); if (getpeername(connected_fd, (struct sockaddr *)client_sa_ptr, &slen) != 0) { @@ -93,6 +105,8 @@ return(-1); } + if(!ReverseMode){ + /* * Build up the pf natlook structure. * Just for IPv4 right now @@ -140,6 +154,9 @@ real_server_sa_ptr->sin_addr.s_addr = natlook.rdaddr.addr32[0]; real_server_sa_ptr->sin_len = sizeof(struct sockaddr_in); real_server_sa_ptr->sin_family = AF_INET; + + } /* !ReverseMode */ + return(0); } --- util.h.orig Tue Mar 12 16:49:47 2002 +++ util.h Tue Mar 12 16:50:12 2002 @@ -56,7 +56,7 @@ 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_server_sa); extern int get_backchannel_socket(int type, int min_port, int max_port, int start_port, int direction, struct sockaddr_in *sap);