README.pwfd 3.5 KB

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