diff -c -r ./ftp-gw/ftp-gw.c ../../fwtk-2.1-violated/fwtk/ftp-gw/ftp-gw.c
*** ./ftp-gw/ftp-gw.c	Thu Feb  5 19:05:43 1998
--- ../../fwtk-2.1-violated/fwtk/ftp-gw/ftp-gw.c	Thu May 21 17:36:09 1998
***************
*** 44,49 ****
--- 44,51 ----
  
  extern	char	*optarg;
  
+ char *getdsthost();
+ 
  #include	"firewall.h"
  
  
***************
*** 88,93 ****
--- 90,97 ----
  static	int			cmdcnt = 0;
  static	int			timeout = PROXY_TIMEOUT;
  
+ static	int			do_transparent = 0;
+ 
  
  static	int	cmd_user();
  static	int	cmd_authorize();
***************
*** 101,106 ****
--- 105,111 ----
  static	int	cmd_passthru();
  static	void	saveline();
  static	void	flushsaved();
+ static	int	connectdest();
  
  #define	OP_CONN	001	/* only valid if connected */
  #define	OP_WCON	002	/* writethrough if connected */
***************
*** 173,178 ****
--- 178,184 ----
  	char		xuf[1024];
  	char		huf[512];
  	char		*passuser = (char *)0;	/* passed user as av */
+ 	char		*psychic, *hotline;
  
  #ifndef	LOG_DAEMON
  	openlog("ftp-gw",LOG_PID);
***************
*** 317,322 ****
--- 323,332 ----
  	} else
  		timeout = PROXY_TIMEOUT;
  
+ 	psychic = getdsthost(0, NULL);
+ 	if (psychic)
+ 		do_transparent++;
+ 
  	/* display a welcome file or message */
  	if(passuser == (char *)0) {
  		if((cf = cfg_get("welcome-msg",confp)) != (Cfg *)0) {
***************
*** 324,329 ****
--- 334,345 ----
  				syslog(LLEV,"fwtkcfgerr: welcome-msg must have one parameter, line %d",cf->ln);
  				exit(1);
  			}
+ 			if (do_transparent) {
+ 				if (sayfile2(0, cf->argv[0], 220)) {
+ 					syslog(LLEV,"fwtksyserr: cannot display welcome %.512s: %m",cf->argv[0]);
+                                 	exit(1);
+ 				}
+ 			} else
  			if(sayfile(0,cf->argv[0],220)) {
  				syslog(LLEV,"fwtksyserr: cannot display welcome %.512s: %m",cf->argv[0]);
  				exit(1);
***************
*** 336,341 ****
--- 352,360 ----
  				if(say(0,"220-Proxy first requires authentication"))
  					exit(1);
  
+ 			if (do_transparent)
+ 			sprintf(xuf, "220-%s FTP proxy (Version %s) ready.",huf, FWTK_VERSION_MINOR);
+ 			else
  			sprintf(xuf, "220 %s FTP proxy (Version %s) ready.",huf, FWTK_VERSION_MINOR);
  			if(say(0,xuf))
  				exit(1);
***************
*** 357,362 ****
--- 376,384 ----
  				exit(1);
  	}
  
+ 	if (do_transparent)
+ 		connectdest(psychic, 21);
+ 
  	/* main loop */
  	while(1) {
  		FD_ZERO(&rdy);
***************
*** 653,658 ****
--- 675,696 ----
  			return(sayn(0,noad,sizeof(noad)-1));
  	}
  
+ 	if (do_transparent) {
+ 		if((rfd == (-1)) && (x = connectdest(dest,port)))
+ 			return x;
+ 
+ 		sprintf(buf,"USER %s",user);
+ 
+ 		if (say(rfd, buf))
+ 			return(1);
+ 
+ 		x = getresp(rfd, buf, sizeof(buf), 1);
+ 		if (sendsaved(0, x))
+ 			return(1);
+ 
+ 		return(say(0, buf));
+ 	}
+ 
  	if(*dest == '\0')
  		dest = "localhost";
  
***************
*** 694,705 ****
  		char	ebuf[512];
  
  		strcpy(ebuf,buf);
! 		sprintf(buf,"521 %s: %s",dest,ebuf);
  		rfd = -1;
  		return(say(0,buf));
  	}
! 	sprintf(buf,"----GATEWAY CONNECTED TO %s----",dest);
! 	saveline(buf);
  
  	/* we are now connected and need to try the autologin thing */
  	x = getresp(rfd,buf,sizeof(buf),1);
--- 732,748 ----
  		char	ebuf[512];
  
  		strcpy(ebuf,buf);
!                 if (do_transparent)
!                         sprintf(buf, "521 %s,%d: %s", dest, ntohs(port), ebuf);
!                 else
! 			sprintf(buf,"521 %s: %s",dest,ebuf);
  		rfd = -1;
  		return(say(0,buf));
  	}
! 	if (!do_transparent) {
! 		sprintf(buf,"----GATEWAY CONNECTED TO %s----",dest);
! 		saveline(buf);
! 	}
  
  	/* we are now connected and need to try the autologin thing */
  	x = getresp(rfd,buf,sizeof(buf),1);
***************
*** 1889,1891 ****
--- 1932,2050 ----
  	dup(nread);
  }
  #endif
+ 
+ static int connectdest(dest, port)
+ char *dest;
+ short port;
+ {
+       char buf[1024], mbuf[512];
+       int msg_int, x;
+ 
+         if(*dest == '\0')
+                 dest = "localhost";
+ 
+         if(validests != (char **)0) {
+                 char    **xp;
+                 int     x;
+ 
+                 for(xp = validests; *xp != (char *)0; xp++) {
+                         if(**xp == '!' && hostmatch(*xp + 1,dest)) {
+                                 return(baddest(0,dest));
+                         } else {
+                                 if(hostmatch(*xp,dest))
+                                         break;
+                         }
+                 }
+                 if(*xp == (char *)0)
+                         return(baddest(0,dest));
+         }
+ 
+         /* Extended permissions processing goes in here for destination */
+         if(extendperm) {
+                 msg_int = auth_perm(confp, authuser, "ftp-gw", dest,(char *)0);
+                 if(msg_int == 1) {
+                         sprintf(mbuf,"Permission denied for user %s to connect to %s",authuser,dest);
+                         syslog(LLEV,"deny host=%s/%s connect to %s user=%s",rladdr,riaddr,dest,authuser);
+                                 say(0,mbuf);
+                                 return(1);
+                 } else {
+                         if(msg_int == -1) {
+                                 sprintf(mbuf,"No match in netperm-table for %s to ftp to %s",authuser,dest);
+                                 say(0,mbuf);
+                                 return(1);
+                         }
+                 }
+         }      
+ 
+         syslog(LLEV,"permit host=%s/%s connect to %s",rladdr,riaddr,dest);
+ 
+         if((rfd = conn_server(dest,port,0,buf)) < 0) {
+                 char    ebuf[512];
+ 
+                 strcpy(ebuf,buf);
+ 		if (do_transparent)
+ 			sprintf(buf,"521 %s,%d: %s",dest,ntohs(port),ebuf);
+ 		else
+                 	sprintf(buf,"521 %s: %s",dest,ebuf);
+                 rfd = -1;
+                 return(say(0,buf));
+         }
+         if (!do_transparent) {
+         	sprintf(buf,"----GATEWAY CONNECTED TO %s----",dest);
+         	saveline(buf);
+ 	}
+ 
+         /* we are now connected and need to try the autologin thing */
+         x = getresp(rfd,buf,sizeof(buf),1);
+         if(x / 100 != COMPLETE) {
+                 sendsaved(0,-1);
+                 return(say(0,buf));
+         }
+         saveline(buf);
+ 
+       sendsaved(0,-1);
+       return 0;
+ }
+ 
+ /* quick hack */
+ sayfile2(fd,fn,code)
+ int     fd;
+ char    *fn;
+ int     code;
+ {
+         FILE    *f;
+         char    buf[BUFSIZ];
+         char    yuf[BUFSIZ];
+         char    *c;
+         int     x;
+         int     saidsomething = 0;
+ 
+         if((f = fopen(fn,"r")) == (FILE *)0)
+                 return(1);
+         while(fgets(buf,sizeof(buf),f) != (char *)0) {
+                 if((c = index(buf,'\n')) != (char *)0)
+                         *c = '\0';
+                 x = fgetc(f);
+                 if(feof(f))
+                         sprintf(yuf,"%3.3d-%s",code,buf);
+                 else {
+                         sprintf(yuf,"%3.3d-%s",code,buf);
+                         ungetc(x,f);
+                 }
+                 if(say(fd,yuf)) {
+                         fclose(f);
+                         return(1);
+                 }
+                 saidsomething++;
+         }
+         fclose(f);
+         if (!saidsomething) {
+                 syslog(LLEV,"fwtkcfgerr: sayfile for %d is empty",code);
+                 sprintf(yuf, "%3.3d The file to display is empty",code);
+                 if(say(fd,yuf)) {
+                         fclose(f);
+                         return(1);
+                 }
+         }
+         return(0);
+ }
diff -c -r ./http-gw/http-gw.c ../../fwtk-2.1-violated/fwtk/http-gw/http-gw.c
*** ./http-gw/http-gw.c	Fri Feb  6 18:32:25 1998
--- ../../fwtk-2.1-violated/fwtk/http-gw/http-gw.c	Thu May 21 17:00:47 1998
***************
*** 27,32 ****
--- 27,35 ----
  static char http_buffer[8192];
  static char reason[8192];
  static	int	checkBrowserType = 1;
+ static	int	do_transparent = 0;
+ 
+ char	* getdsthost();
  
  static void do_logging()
  {	char *proto = "GOPHER";
***************
*** 473,478 ****
--- 476,490 ----
  	/*(NOT A SPECIAL FORM)*/
  
  		if((rem_type & TYPE_LOCAL)== 0){
+                         char * psychic = getdsthost(sockfd, &def_port);
+                         if (psychic) {
+                                 if (strlen(psychic) <= MAXHOSTNAMELEN) {
+                                         do_transparent ++;
+                                         strncpy(def_httpd, psychic, strlen(psychic));
+                                         strncpy(def_server, psychic, strlen(psychic));
+                                 }
+                         }
+                         
  /*  See if it can be forwarded */
  
  			if( can_forward(buf)){
***************
*** 1564,1570 ****
  				    		    parse_vec[0], 
  						    parse_vec[1],
  				    		    ourname, ourport);
! 				    }else{
  					    sprintf(new_reply,"%s\tgopher://%s:%s/%c%s\t%s\t%u",
  						    parse_vec[0], parse_vec[2],
  						    parse_vec[3], chk_type_ch,
--- 1576,1589 ----
  				    		    parse_vec[0], 
  						    parse_vec[1],
  				    		    ourname, ourport);
! 				    }
! 				    else
! 				    if (do_transparent) {
! 					    sprintf(new_reply, "%s\t%s\t%s\t%s",
! 							parse_vec[0], parse_vec[1],
! 							parse_vec[2],parse_vec[3]);
! 				    }
! 				    else {
  					    sprintf(new_reply,"%s\tgopher://%s:%s/%c%s\t%s\t%u",
  						    parse_vec[0], parse_vec[2],
  						    parse_vec[3], chk_type_ch,
diff -c -r ./lib/hnam.c ../../fwtk-2.1-violated/fwtk/lib/hnam.c
*** ./lib/hnam.c	Tue Dec 10 13:08:48 1996
--- ../../fwtk-2.1-violated/fwtk/lib/hnam.c	Thu May 21 17:10:00 1998
***************
*** 23,28 ****
--- 23,33 ----
  
  #include	"firewall.h"
  
+ #ifdef __FreeBSD__ /* or OpenBSD, NetBSD, BSDI, etc. Fix this for your system. */
+ #include	<net/if.h>
+ #include	"ip_nat.h"
+ #endif /* __FreeBSD__ */
+ 
  
  char	*
  maphostname(name)
***************
*** 49,52 ****
--- 54,132 ----
  	}
  	bcopy(hp->h_addr,&sin.sin_addr,hp->h_length);
  	return(inet_ntoa(sin.sin_addr));
+ }
+ 
+ char *getdsthost(fd, ptr)
+ int fd;
+ int *ptr;
+ {
+ 	struct sockaddr_in sin;
+ 	struct hostent	   * hp;
+ 	int		   sl = sizeof(struct sockaddr_in), err = 0, local_h = 0, i = 0;
+ 	char		   buf[255], hostbuf[255];
+ #ifdef __FreeBSD__
+ 	struct sockaddr_in rsin;
+ 	struct natlookup   natlookup;
+ #endif
+ 
+ #ifdef linux
+ 	if (!(err = getsockname(0, &sin, &sl))) {
+ 		if(ptr)	
+ 			* ptr = ntohs(sin.sin_port);
+ 
+ 		sprintf(buf, "%s", inet_ntoa(sin.sin_addr));
+ 		gethostname(hostbuf, 254);
+ 		hp = gethostbyname(hostbuf);
+ 		while (hp->h_addr_list[i]) {
+ 			bzero(&sin, &sl);
+ 			memcpy(&sin.sin_addr, hp->h_addr_list[i++],
+ 				sizeof(hp->h_addr_list[i++]));
+ 
+ 			if (!strcmp(buf, inet_ntoa(sin.sin_addr)))
+ 				local_h++;
+ 		}
+ 
+ 		if(local_h)
+ 			return(NULL);
+ 		else
+ 			return(buf);
+  }
+ #endif
+ 
+ #ifdef __FreeBSD__
+ /*  The basis for this block of code is Darren Reed's
+  *  patches to the TIS ftwk's ftp-gw.
+  */
+ 	bzero((char*)&sin, sizeof(sin));
+ 	bzero((char*)&rsin, sizeof(rsin));
+ 
+ 	if (getsockname(fd, (struct sockaddr*)&sin, &sl) < 0)
+ 		return NULL;
+ 
+ 	sl = sizeof(rsin);
+ 
+ 	if(getpeername(fd, (struct sockaddr*)&rsin, &sl) < 0)
+ 		return NULL;
+ 
+ 	natlookup.nl_inport=sin.sin_port;
+ 	natlookup.nl_outport=rsin.sin_port;
+ 	natlookup.nl_inip=sin.sin_addr;
+ 	natlookup.nl_outip=rsin.sin_addr;
+ 
+ 	if ((natfd = open("/dev/ipl",O_RDONLY)) < 0)
+ 		return NULL;
+ 
+ 	if (ioctl(natfd, SIOCGNATL,&natlookup) == (-1))
+ 		return NULL;
+ 
+ 	close(natfd);
+ 
+ 	if (ptr)
+ 		*ptr = ntohs(natlookup.nl_inport);
+ 
+ 	sprintf(buf, "%s", inet_ntoa(natlookup.nl_inip));
+ #endif
+ 
+ 	/* No transparent proxy support */
+ 	return(NULL);
  }
diff -c -r ./plug-gw/plug-gw.c ../../fwtk-2.1-violated/fwtk/plug-gw/plug-gw.c
*** ./plug-gw/plug-gw.c	Thu Feb  5 19:07:35 1998
--- ../../fwtk-2.1-violated/fwtk/plug-gw/plug-gw.c	Thu May 21 17:29:01 1998
***************
*** 43,48 ****
--- 43,50 ----
  static	char		**validdests = (char **)0;
  static 	int		net_write();
  
+ static	int		do_transparent = 0;
+ 
  main(ac,av)
  int	ac;
  char	*av[];
***************
*** 198,206 ****
--- 200,220 ----
  	char		*ptr;
  	int		state = 0;
  	int		ssl_plug = 0;
+ 	char		* getdsthost();
+ 	int		pport = 0;
  
  	struct timeval	timo;
  
+ 	/* Transparent plug-gw is probably a bad idea, but then, plug-gw is a bad
+ 	 * idea ..
+ 	 */
+ 	dhost = getdsthost(0, &pport);
+ 	if (dhost) {
+ 		do_transparent++;
+ 		portid = pport;
+ 	}
+ 
+ 
  	if(c->flags & PERM_DENY) {
  		if (p == -1)
  			syslog(LLEV,"deny host=%.512s/%.20s port=any",rhost,raddr);
***************
*** 220,226 ****
  				syslog(LLEV,"fwtkcfgerr: -plug-to takes an argument, line %d",c->ln);
  				exit (1);
  			}
! 			dhost = av[x];
  			continue;
  		}
  
--- 234,241 ----
  				syslog(LLEV,"fwtkcfgerr: -plug-to takes an argument, line %d",c->ln);
  				exit (1);
  			}
! 			if (!dhost)
! 				dhost = av[x];
  			continue;
  		}
  
diff -c -r ./rlogin-gw/rlogin-gw.c ../../fwtk-2.1-violated/fwtk/rlogin-gw/rlogin-gw.c
*** ./rlogin-gw/rlogin-gw.c	Thu Feb  5 19:08:38 1998
--- ../../fwtk-2.1-violated/fwtk/rlogin-gw/rlogin-gw.c	Thu May 21 17:20:25 1998
***************
*** 103,108 ****
--- 103,111 ----
  static	int		trusted = 0;
  static	int		doX = 0;
  static	char		*prompt;
+ static	int		do_transparent = 0;
+ 
+ char			* getdsthost();
  
  main(ac,av)
  int	ac;
***************
*** 123,128 ****
--- 126,132 ----
  	static char	*tokav[56];
  	int		tokac;
  	struct timeval	timo;
+ 	char		* psychic;
  
  #ifndef	LOG_NDELAY
  	openlog("rlogin-gw",LOG_PID);
***************
*** 188,194 ****
  		xforwarder = cf->argv[0];
  	}
  
! 
  
  	if((cf = cfg_get("directory",confp)) != (Cfg *)0) {
  		if(cf->argc != 1) {
--- 192,203 ----
  		xforwarder = cf->argv[0];
  	}
  
! 	psychic = getdsthost(0, NULL);
! 	if (psychic) {
! 		do_transparent++;
! 		strncpy(dest, psychic, 511);
! 		dest[511] = '\0';
! 	}
  
  	if((cf = cfg_get("directory",confp)) != (Cfg *)0) {
  		if(cf->argc != 1) {
***************
*** 266,271 ****
--- 275,281 ----
  	if((p = index(rusername,'@')) != (char *)0) {
  		char	*namp;
  
+ 		dest[0] = '\0';
  		*p++ = '\0';
  		if(*p == '\0')
  			p = "localhost";
***************
*** 297,302 ****
--- 307,326 ----
  
  	if(dest[0] != '\0') {
  /* Setup connection directly to remote machine */
+ 		if ((cf = cfg_get("welcome-msg",confp)) != (Cfg *)0) {
+ 			if (cf->argc != 1) {
+ 				syslog(LLEV,"fwtkcfgerr: welcome-msg must have one parameter, line %d",cf->ln);
+ 				exit(1);
+ 			}
+ 
+ 			if (sayfile(0, cf->argv[0])) {
+ 				syslog(LLEV,"fwtksyserr: cannot display welcome %s: %m",cf->argv[0]);
+ 				exit(1);
+ 			}
+ 		}
+ 
+ 		/* Hey fwtk developer people -- this connect_dest thing is *nasty!* */
+ 
  		sprintf(buf,"connect %.1000s",dest);
  		tokac = enargv(buf, tokav, 56, tokbuf, sizeof(tokbuf));
  		if (cmd_connect(tokac, tokav, buf) != 2)
***************
*** 535,548 ****
  		char	ebuf[512];
  
  		syslog(LLEV,"permit host=%.512s/%.20s connect to %.512s",rhost,raddr,namp);
! 		if(strlen(namp) > 20)
! 			namp[20] = '\0';
! 		if(rusername[0] != '\0')
! 			sprintf(ebuf,"Trying %s@%s...",rusername,namp);
! 		else
! 			sprintf(ebuf,"Trying %s...",namp);
! 		if(say(0,ebuf))
! 			return(1);
  	} else
  		syslog(LLEV,"permit host=%.512s/%.20s connect to %.512s",rhost,raddr,av[1]);
  	if((serfd = conn_server(av[1],RLOGINPORT,1,buf)) < 0) {
--- 559,574 ----
  		char	ebuf[512];
  
  		syslog(LLEV,"permit host=%.512s/%.20s connect to %.512s",rhost,raddr,namp);
! 		if (!do_transparent) {
! 			if(strlen(namp) > 20)
! 				namp[20] = '\0';
! 			if(rusername[0] != '\0')
! 				sprintf(ebuf,"Trying %s@%s...",rusername,namp);
! 			else
! 				sprintf(ebuf,"Trying %s...",namp);
! 			if(say(0,ebuf))
! 				return(1);
! 		}
  	} else
  		syslog(LLEV,"permit host=%.512s/%.20s connect to %.512s",rhost,raddr,av[1]);
  	if((serfd = conn_server(av[1],RLOGINPORT,1,buf)) < 0) {
diff -c -r ./tn-gw/tn-gw.c ../../fwtk-2.1-violated/fwtk/tn-gw/tn-gw.c
*** ./tn-gw/tn-gw.c	Thu Feb  5 19:11:36 1998
--- ../../fwtk-2.1-violated/fwtk/tn-gw/tn-gw.c	Thu May 21 17:25:06 1998
***************
*** 91,96 ****
--- 91,100 ----
  static	int			cmd_xforward();
  static	int			cmd_timeout();
  
+ char				* getdsthost();
+ 
+ static	int			do_transparent = 0;
+ 
  static	int			tn3270 = 1;	/* don't do tn3270 stuff */
  static	int			doX;
  
***************
*** 144,149 ****
--- 148,155 ----
  	char		tokbuf[BSIZ];
  	char		*tokav[56];
  	int		tokac;
+ 	int		port;
+ 	char		* psychic;
  
  #ifndef	LOG_DAEMON
  	openlog("tn-gw",LOG_PID);
***************
*** 325,330 ****
--- 331,362 ----
  		}
  	}
  
+ 	psychic = getdsthost(0, &port);
+ 	if (psychic) {
+ 		if ((strlen(psychic) + 10) < 510) {
+ 			do_transparent++;
+ 			if (port)
+ 				sprintf(dest, "%s:%d", psychic, port);
+ 			else
+ 				sprintf(dest, "%s", psychic);
+  
+ 			if (!welcomedone)
+ 				if ((cf = cfg_get("welcome-msg", confp)) != (Cfg *)0) {
+ 					if (cf->argc != 1) {
+ 						syslog(LLEV,"fwtkcfgerr: welcome-msg must have one parameter, line %d",cf->ln);
+ 						exit(1);
+ 					}
+ 
+ 					if (sayfile(0, cf->argv[0])) {
+ 						syslog(LLEV,"fwtksyserr: cannot display welcome %s:%m",cf->argv[0]);
+ 						exit(1);
+ 					}
+ 
+ 					welcomedone = 1;
+ 				}
+ 		}
+ 	}
+ 
  	while (argc > 1) {
  		argc--;
  		argv++;
***************
*** 947,955 ****
  		char	ebuf[512];
  
  		syslog(LLEV,"permit host=%.512s/%.20s destination=%.512s",rladdr,riaddr,namp);
! 		sprintf(ebuf,"Trying %.100s port %d...",namp,port);
! 		if(say(0,ebuf))
! 			return(1);
  	} else
  		syslog(LLEV,"permit host=%.512s/%.20s destination=%.512s",rladdr,riaddr,av[1]);
  
--- 979,989 ----
  		char	ebuf[512];
  
  		syslog(LLEV,"permit host=%.512s/%.20s destination=%.512s",rladdr,riaddr,namp);
! 		if (!do_transparent) {
! 			sprintf(ebuf,"Trying %.100s port %d...",namp,port);
! 			if(say(0,ebuf))
! 				return(1);
! 		}
  	} else
  		syslog(LLEV,"permit host=%.512s/%.20s destination=%.512s",rladdr,riaddr,av[1]);
  
***************
*** 991,998 ****
  
  	syslog(LLEV,"connected host=%.512s/%.20s destination=%.512s",rladdr,riaddr,av[1]);
  	strncpy(dest,av[1], 511);
! 	sprintf(buf, "Connected to %.512s.", dest);
! 	say(0, buf);
  	return(2);
  }
  
--- 1025,1034 ----
  
  	syslog(LLEV,"connected host=%.512s/%.20s destination=%.512s",rladdr,riaddr,av[1]);
  	strncpy(dest,av[1], 511);
! 	if (!do_transparent) {
! 		sprintf(buf, "Connected to %.512s.", dest);
! 		say(0, buf);
! 	}
  	return(2);
  }
  
