--- ppp-2.4.1/pppd/plugins/Makefile.linux	Mon Aug 13 17:05:22 2001
+++ ppp-2.4.1.pwfd/pppd/plugins/Makefile.linux	Mon Aug 13 17:08:01 2001
@@ -1,9 +1,9 @@
 CC	= gcc
-CFLAGS	= -g -O2 -I.. -I../../include -fPIC
+CFLAGS	= -Wall -O2 -I.. -I../../include -fPIC
 LDFLAGS	= -shared
 INSTALL	= install
 
-all:	minconn.so passprompt.so pppoe/pppoe.so
+all:	minconn.so passprompt.so passwordfd.so pppoe/pppoe.so
 	$(MAKE) -C pppoe $(MFLAGS) all
 
 pppoe/pppoe.so:
@@ -15,9 +15,12 @@
 passprompt.so: passprompt.c
 	$(CC) -o $@ $(LDFLAGS) $(CFLAGS) passprompt.c
 
+passwordfd.so: passwordfd.c
+	$(CC) -o $@ $(LDFLAGS) $(CFLAGS) passwordfd.c
+
 LIBDIR	= $(DESTDIR)/usr/lib/pppd
 
-install: minconn.so passprompt.so pppoe/pppoe.so
+install: minconn.so passprompt.so passwordfd.so pppoe/pppoe.so
 	version=`awk -F '"' '/VERSION/ { print $$2; }' ../patchlevel.h`; \
 	$(INSTALL) -d $(LIBDIR)/$$version; \
 	$(INSTALL) $? $(LIBDIR)/$$version
 
--- ppp-2.4.1/linux/Makefile.top
+++ ppp-2.4.1.pwfd/linux/Makefile.top	2000/09/11 15:15:23
@@ -11,6 +11,7 @@
 all:
 	cd chat; $(MAKE) $(MFLAGS) all
 	cd pppd; $(MAKE) $(MFLAGS) all
+	cd pppd/plugins; $(MAKE) $(MFLAGS) all
 	cd pppstats; $(MAKE) $(MFLAGS) all
 	cd pppdump; $(MAKE) $(MFLAGS) all
 
@@ -19,6 +20,7 @@
 install-progs:
 	cd chat; $(MAKE) BINDIR=$(BINDIR) MANDIR=$(MANDIR) $(MFLAGS) install
 	cd pppd; $(MAKE) BINDIR=$(BINDIR) MANDIR=$(MANDIR) $(MFLAGS) install
+	cd pppd/plugins; $(MAKE) BINDIR=$(BINDIR) MANDIR=$(MANDIR) $(MFLAGS) install
 	cd pppstats; $(MAKE) BINDIR=$(BINDIR) MANDIR=$(MANDIR) $(MFLAGS) install
 	cd pppdump; $(MAKE) BINDIR=$(BINDIR) MANDIR=$(MANDIR) $(MFLAGS) install
 
@@ -45,6 +47,7 @@
 	rm -f `find . -name '*~' -print`
 	cd chat; $(MAKE) clean
 	cd pppd; $(MAKE) clean
+	cd pppd/plugins; $(MAKE) clean
 	cd pppstats; $(MAKE) clean
 	cd pppdump; $(MAKE) clean
 
--- ppp-2.4.1/pppd/auth.c
+++ ppp-2.4.1.pwfd/pppd/auth.c	2000/09/11 16:06:32
@@ -132,6 +132,9 @@
 /* Hook for a plugin to get the PAP password for authenticating us */
 int (*pap_passwd_hook) __P((char *user, char *passwd)) = NULL;
 
+/* Hook for a plugin to get the CHAP password for authenticating us */
+int (*chap_passwd_hook) __P((char *user, char *passwd)) = NULL;
+
 /*
  * This is used to ensure that we don't start an auth-up/down
  * script while one is already running.
@@ -1319,7 +1322,16 @@
     int ret;
     char *filename;
     struct wordlist *addrs;
-
+    
+    /*
+     * Check whether a plugin wants to supply this.
+     */
+    if (chap_passwd_hook) {
+      ret = (*chap_passwd_hook)(client, NULL);
+      if (ret >= 0)
+	return ret;
+    }
+    
     filename = _PATH_CHAPFILE;
     f = fopen(filename, "r");
     if (f == NULL)
@@ -1363,7 +1375,17 @@
     char *filename;
     struct wordlist *addrs, *opts;
     char secbuf[MAXWORDLEN];
-
+    
+    /*
+     * Check whether a plugin wants to supply this.
+     */
+    if (chap_passwd_hook) {
+      secbuf[0] = 0;
+      ret = (*chap_passwd_hook)(user, secbuf);
+      if (ret >= 0)
+	goto done;
+    }
+    
     if (!am_server && passwd[0] != 0) {
 	strlcpy(secbuf, passwd, sizeof(secbuf));
     } else {
@@ -1390,7 +1412,9 @@
 	if (addrs != 0)
 	    free_wordlist(addrs);
     }
-
+    
+ done:
+    
     len = strlen(secbuf);
     if (len > MAXSECRETLEN) {
 	error("Secret for %s on %s is too long", client, server);
--- ppp-2.4.1/pppd/plugins/passwordfd.c
+++ ppp-2.4.1.pwfd/pppd/plugins/passwordfd.c	2000/09/11 16:08:51
@@ -0,0 +1,93 @@
+
+/*
+ *  Author: Arvin Schnell <arvin@suse.de>
+ *
+ *  This plugin let's you pass the password to the pppd via
+ *  a file descriptor. That's easy and secure - no fiddling
+ *  with pap- and chap-secrets files.
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "pppd.h"
+
+char pppd_version[] = VERSION;
+
+static int passwdfd = -1;
+static char save_passwd[MAXSECRETLEN];
+
+static option_t options[] = {
+    { "passwordfd", o_int, &passwdfd,
+      "Receive password on this file descriptor" },
+    { NULL }
+};
+
+static int get_passwd (char *user, char *passwd)
+{
+    int readgood, red;
+
+    if (passwdfd == -1)
+	return -1;
+
+    if (passwd == NULL)
+	return 1;
+
+    if (passwdfd == -2) {
+	strcpy (passwd, save_passwd);
+	return 1;
+    }
+
+    readgood = 0;
+    do {
+	red = read (passwdfd, passwd + readgood, MAXSECRETLEN - 1 - readgood);
+	if (red == 0)
+	    break;
+	if (red < 0) {
+	    error ("Can't read secret from fd\n");
+	    readgood = -1;
+	    break;
+	}
+	readgood += red;
+    } while (readgood < MAXSECRETLEN - 1);
+
+    close (passwdfd);
+
+    if (readgood < 0)
+	return 0;
+
+    passwd[readgood] = 0;
+    strcpy (save_passwd, passwd);
+    passwdfd = -2;
+
+    return 1;
+}
+
+static int get_pap_passwd (char *user, char *passwd)
+{
+    int ret = get_passwd (user, passwd);
+#if 0
+    error ("get_pap_passwd (\"%s\", \"%s\") = %d", user ? user : "(null)",
+	passwd ? passwd : "(null)", ret);
+#endif
+    return ret;
+}
+
+static int get_chap_passwd (char *user, char *passwd)
+{
+    int ret = get_passwd (user, passwd);
+#if 0
+    error ("get_chap_passwd (\"%s\", \"%s\") = %d", user ? user : "(null)",
+	passwd ? passwd : "(null)", ret);
+#endif
+    return ret;
+}
+
+void plugin_init (void)
+{
+    add_options (options);
+    pap_passwd_hook = get_pap_passwd;
+    chap_passwd_hook = get_chap_passwd;
+}
--- ppp-2.4.1/pppd/pppd.h
+++ ppp-2.4.1.pwfd/pppd/pppd.h	2000/09/11 15:15:23
@@ -489,6 +489,7 @@
 				 struct wordlist **popts));
 extern void (*pap_logout_hook) __P((void));
 extern int (*pap_passwd_hook) __P((char *user, char *passwd));
+extern int (*chap_passwd_hook) __P((char *user, char *passwd));
 extern void (*ip_up_hook) __P((void));
 extern void (*ip_down_hook) __P((void));
 
