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