blob: f6c5d9b8dff84ccb7d2607de2a67add67475dcac [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001
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