Subject: Installing pgp as a filter in ftpconversions

From: Quentin Fennessy <[email-masked]>
Date: Mon, 11 Mar 1996 12:53:16 -0600

I am trying to install pgp as a filter in ftpconversions in order
to encrypt files as they are transferred.  I have installed a line
like this in ftpconversions:

	 :   : :.joe:/bin/pgpw joesmith %s:T_REG:O_DESED:DESED

/bin/pgpw is a wrapper around pgp that causes pgp to encrypt the
file argument with joesmith's public key.  I have tested pgpw in
a chrooted environment and it does work well.  pgpw writes the
encrypted file stream to stdout (as does pgp).

However I cannot make it work for ftp transfers.  I see this when
I try:

	ftp> get passwd.joe
	200 PORT command successful.
	150 Opening BINARY mode data connection for /bin/pgpw.
	226 Transfer complete.
	ftp> 

The file transferred (passwd.joe) is zero-length.

I have been able to install other filters successfully.  The difference
is that pgpw is a wrapper around another binary, and I cannot make
such a wrapper work.  (Wrapper is necessary because pgp in filter mode
demands its input from stdin, rather than from a filename on the
command line).  I have included my wrapper (pipe stuff) below.

Has anyone else solved this problem?

Details:
	IBM AIX 3.2.5
	WU-FTP 2.4

Thanks,
	Quentin

/*

This does not work yet!

	Run this program as:

			pgpw userid input-file

	and it will run pgp like this:

			pgp -fe userid < input-file

	This is also designed to work in a chrooted environment, where
	pgp is found in /bin/pgp.  Won't work outside such an
	environment without changing the pgp path.

	Code taken from Stevens APUE.

SCCS:	%W%	%G%
 */

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <malloc.h>
#include <unistd.h>
#include <sys/wait.h>

#ifdef _AIX
#include <sys/access.h>
#endif

#define BUFIZ 1024

#ifdef DEBUG
#define PGPCMD "/usr/sww/bin/pgp"
#else
#define PGPCMD "/bin/pgp"
#endif

#define PGPARGS "-fe"

main(int argc, char *argv[])
{
	char *usage =		"usage: %s userid filename\n";

	char *prog =		argv[0];
	char *userid =		argv[1];
	char *dfil =		argv[2];

	char *pgpcmd =		PGPCMD;
	char *pgpargs = 	PGPARGS;
	char *pgp =			"pgp";

	int		c, fd[2];
	pid_t 	pid;
	FILE	*fpin;

	if (argc != 3) {
		(void)printf(usage,prog);
		exit(1);
	}

	if ((fpin = fopen(dfil, "r")) == NULL) {
		perror(prog);
		exit(1);
	}

	if (pipe(fd) < 0)
		perror("pipe error");

	if ( (pid = fork()) < 0)
		perror("pipe error");
	else if (pid > 0) {			/* parent */
		close(fd[0]);

		while ((c = getc(fpin)) != EOF)
			if (write(fd[1], &c, 1) < 0)
				perror("write error writing to pipe");

		if (ferror(fpin))
			perror("getc error");
		
		close(fd[1]);

		if (waitpid(pid, NULL, 0) < 0)
			perror("waitpid error");

		exit(0);

	} else {					/* child */

		close(fd[1]);

		if (fd[0] != STDIN_FILENO) {
			if (dup2(fd[0], STDIN_FILENO) != STDIN_FILENO)
					perror("dup2 error to stdin");
			close(fd[0]);
		} 
	
		if (execl(pgpcmd, pgp, pgpargs, userid, (char *)0))
			perror("execl error for pgp");
	}
}