xref: /netbsd-src/external/bsd/ppp/dist/README.pwfd (revision a619718e42cf7022332d544fd5ec5713434707ac)
1*a619718eSchristos
2*a619718eSchristos	Support to pass the password via a pipe to the pppd
3*a619718eSchristos	---------------------------------------------------
4*a619718eSchristos
5*a619718eSchristos	Arvin Schnell <arvin@suse.de>
6*a619718eSchristos	2002-02-08
7*a619718eSchristos
8*a619718eSchristos
9*a619718eSchristos1. Introduction
10*a619718eSchristos---------------
11*a619718eSchristos
12*a619718eSchristosNormally programs like wvdial or kppp read the online password from their
13*a619718eSchristosconfig file and store them in the pap- and chap-secrets before they start the
14*a619718eSchristospppd and remove them afterwards. Sure they need special privileges to do so.
15*a619718eSchristos
16*a619718eSchristosThe passwordfd feature offers a simpler and more secure solution. The program
17*a619718eSchristosthat starts the pppd opens a pipe and writes the password into it. The pppd
18*a619718eSchristossimply reads the password from that pipe.
19*a619718eSchristos
20*a619718eSchristosThis methods is used for quite a while on SuSE Linux by the programs wvdial,
21*a619718eSchristoskppp and smpppd.
22*a619718eSchristos
23*a619718eSchristos
24*a619718eSchristos2. Example
25*a619718eSchristos----------
26*a619718eSchristos
27*a619718eSchristosHere is a short C program that uses the passwordfd feature. It starts the pppd
28*a619718eSchristosto buildup a pppoe connection.
29*a619718eSchristos
30*a619718eSchristos
31*a619718eSchristos--snip--
32*a619718eSchristos
33*a619718eSchristos#include <stdio.h>
34*a619718eSchristos#include <stdlib.h>
35*a619718eSchristos#include <unistd.h>
36*a619718eSchristos#include <signal.h>
37*a619718eSchristos#include <string.h>
38*a619718eSchristos#include <paths.h>
39*a619718eSchristos
40*a619718eSchristos#ifndef _PATH_PPPD
41*a619718eSchristos#define _PATH_PPPD "/usr/sbin/pppd"
42*a619718eSchristos#endif
43*a619718eSchristos
44*a619718eSchristos
45*a619718eSchristos// Of course these values can be read from a configuration file or
46*a619718eSchristos// entered in a graphical dialog.
47*a619718eSchristoschar *device = "eth0";
48*a619718eSchristoschar *username = "1122334455661122334455660001@t-online.de";
49*a619718eSchristoschar *password = "hello";
50*a619718eSchristos
51*a619718eSchristospid_t pid = 0;
52*a619718eSchristos
53*a619718eSchristos
54*a619718eSchristosvoid
55*a619718eSchristossigproc (int src)
56*a619718eSchristos{
57*a619718eSchristos    fprintf (stderr, "Sending signal %d to pid %d\n", src, pid);
58*a619718eSchristos    kill (pid, src);
59*a619718eSchristos    exit (EXIT_SUCCESS);
60*a619718eSchristos}
61*a619718eSchristos
62*a619718eSchristos
63*a619718eSchristosvoid
64*a619718eSchristossigchild (int src)
65*a619718eSchristos{
66*a619718eSchristos    fprintf (stderr, "Daemon died\n");
67*a619718eSchristos    exit (EXIT_SUCCESS);
68*a619718eSchristos}
69*a619718eSchristos
70*a619718eSchristos
71*a619718eSchristosint
72*a619718eSchristosstart_pppd ()
73*a619718eSchristos{
74*a619718eSchristos    signal (SIGINT, &sigproc);
75*a619718eSchristos    signal (SIGTERM, &sigproc);
76*a619718eSchristos    signal (SIGCHLD, &sigchild);
77*a619718eSchristos
78*a619718eSchristos    pid = fork ();
79*a619718eSchristos    if (pid < 0) {
80*a619718eSchristos	fprintf (stderr, "unable to fork() for pppd: %m\n");
81*a619718eSchristos	return 0;
82*a619718eSchristos    }
83*a619718eSchristos
84*a619718eSchristos    if (pid == 0) {
85*a619718eSchristos
86*a619718eSchristos	int i, pppd_argc = 0;
87*a619718eSchristos	char *pppd_argv[20];
88*a619718eSchristos	char buffer[32] = "";
89*a619718eSchristos	int pppd_passwdfd[2];
90*a619718eSchristos
91*a619718eSchristos	for (i = 0; i < 20; i++)
92*a619718eSchristos	    pppd_argv[i] = NULL;
93*a619718eSchristos
94*a619718eSchristos	pppd_argv[pppd_argc++] = "pppd";
95*a619718eSchristos
96*a619718eSchristos	pppd_argv[pppd_argc++] = "call";
97*a619718eSchristos	pppd_argv[pppd_argc++] = "pwfd-test";
98*a619718eSchristos
99*a619718eSchristos	// The device must be after the call, since the call loads the plugin.
100*a619718eSchristos	pppd_argv[pppd_argc++] = device;
101*a619718eSchristos
102*a619718eSchristos	pppd_argv[pppd_argc++] = "user";
103*a619718eSchristos	pppd_argv[pppd_argc++] = username;
104*a619718eSchristos
105*a619718eSchristos	// Open a pipe to pass the password to pppd.
106*a619718eSchristos	if (pipe (pppd_passwdfd) == -1) {
107*a619718eSchristos	    fprintf (stderr, "pipe failed: %m\n");
108*a619718eSchristos	    exit (EXIT_FAILURE);
109*a619718eSchristos	}
110*a619718eSchristos
111*a619718eSchristos	// Of course this only works it the password is shorter
112*a619718eSchristos	// than the pipe buffer. Otherwise you have to fork to
113*a619718eSchristos	// prevent that your main program blocks.
114*a619718eSchristos	write (pppd_passwdfd[1], password, strlen (password));
115*a619718eSchristos	close (pppd_passwdfd[1]);
116*a619718eSchristos
117*a619718eSchristos	// Tell the pppd to read the password from the fd.
118*a619718eSchristos	pppd_argv[pppd_argc++] = "passwordfd";
119*a619718eSchristos	snprintf (buffer, 32, "%d", pppd_passwdfd[0]);
120*a619718eSchristos	pppd_argv[pppd_argc++] = buffer;
121*a619718eSchristos
122*a619718eSchristos	if (execv (_PATH_PPPD, (char **) pppd_argv) < 0) {
123*a619718eSchristos	    fprintf (stderr, "cannot execl %s: %m\n", _PATH_PPPD);
124*a619718eSchristos	    exit (EXIT_FAILURE);
125*a619718eSchristos	}
126*a619718eSchristos    }
127*a619718eSchristos
128*a619718eSchristos    pause ();
129*a619718eSchristos
130*a619718eSchristos    return 1;
131*a619718eSchristos}
132*a619718eSchristos
133*a619718eSchristos
134*a619718eSchristosint
135*a619718eSchristosmain (int argc, char **argv)
136*a619718eSchristos{
137*a619718eSchristos    if (start_pppd ())
138*a619718eSchristos	exit (EXIT_SUCCESS);
139*a619718eSchristos
140*a619718eSchristos    exit (EXIT_FAILURE);
141*a619718eSchristos}
142*a619718eSchristos
143*a619718eSchristos---snip---
144*a619718eSchristos
145*a619718eSchristos
146*a619718eSchristosCopy this file to /etc/ppp/peers/pwfd-test. The plugins can't be loaded on the
147*a619718eSchristoscommand line (unless you are root) since the plugin option is privileged.
148*a619718eSchristos
149*a619718eSchristos
150*a619718eSchristos---snip---
151*a619718eSchristos
152*a619718eSchristos#
153*a619718eSchristos# PPPoE plugin for kernel 2.4
154*a619718eSchristos#
155*a619718eSchristosplugin pppoe.so
156*a619718eSchristos
157*a619718eSchristos#
158*a619718eSchristos# This plugin enables us to pipe the password to pppd, thus we don't have
159*a619718eSchristos# to fiddle with pap-secrets and chap-secrets. The user is also passed
160*a619718eSchristos# on the command line.
161*a619718eSchristos#
162*a619718eSchristosplugin passwordfd.so
163*a619718eSchristos
164*a619718eSchristosnoauth
165*a619718eSchristosusepeerdns
166*a619718eSchristosdefaultroute
167*a619718eSchristoshide-password
168*a619718eSchristosnodetach
169*a619718eSchristosnopcomp
170*a619718eSchristosnovjccomp
171*a619718eSchristosnoccp
172*a619718eSchristos
173*a619718eSchristos---snip---
174*a619718eSchristos
175