]> git.ozlabs.org Git - ppp.git/blobdiff - pppd/plugins/passprompt.c
The use of <net/ppp_defs.h> isn't guranteed to exist on Linux (e.g. uclibc, buildroot...
[ppp.git] / pppd / plugins / passprompt.c
index 1d885fcea53ba53fa732381ad69be3737def9ad5..14a199f8c743e574a71538d996998fd0361fcafe 100644 (file)
@@ -8,15 +8,19 @@
  *  as published by the Free Software Foundation; either version
  *  2 of the License, or (at your option) any later version.
  */
+
 #include <errno.h>
 #include <unistd.h>
 #include <sys/wait.h>
+#include <sys/param.h>
+#include <limits.h>
 #include <syslog.h>
-#include "pppd.h"
+#include <pppd/pppd.h>
 
-char pppd_version[] = VERSION;
+char pppd_version[] = PPPD_VERSION;
 
 static char promptprog[PATH_MAX+1];
+static int promptprog_refused = 0;
 
 static option_t options[] = {
     { "promptprog", o_string, promptprog,
@@ -29,10 +33,10 @@ static int promptpass(char *user, char *passwd)
 {
     int p[2];
     pid_t kid;
-    int readgood, wstat;
+    int readgood, wstat, ret;
     ssize_t red;
 
-    if (promptprog[0] == 0 || access(promptprog, X_OK) < 0)
+    if (promptprog_refused || promptprog[0] == 0 || access(promptprog, X_OK) < 0)
        return -1;      /* sorry, can't help */
 
     if (!passwd)
@@ -54,8 +58,14 @@ static int promptpass(char *user, char *passwd)
        sys_close();
        closelog();
        close(p[0]);
-       seteuid(getuid());
-       setegid(getgid());
+       ret = seteuid(getuid());
+       if (ret != 0) {
+               warn("Couldn't set effective user id");
+       }
+       ret = setegid(getgid());
+       if (ret != 0) {
+               warn("Couldn't set effective user id");
+       }
        argv[0] = promptprog;
        argv[1] = user;
        argv[2] = remote_name;
@@ -74,7 +84,7 @@ static int promptpass(char *user, char *passwd)
        if (red == 0)
            break;
        if (red < 0) {
-           if (errno == EINTR)
+           if (errno == EINTR && !got_sigterm)
                continue;
            error("Can't read secret from %s: %m", promptprog);
            readgood = -1;
@@ -82,12 +92,11 @@ static int promptpass(char *user, char *passwd)
        }
        readgood += red;
     } while (readgood < MAXSECRETLEN - 1);
-    passwd[readgood] = 0;
     close(p[0]);
 
     /* now wait for child to exit */
     while (waitpid(kid, &wstat, 0) < 0) {
-       if (errno != EINTR) {
+       if (errno != EINTR || got_sigterm) {
            warn("error waiting for %s: %m", promptprog);
            break;
        }
@@ -95,11 +104,17 @@ static int promptpass(char *user, char *passwd)
 
     if (readgood < 0)
        return 0;
+    passwd[readgood] = 0;
     if (!WIFEXITED(wstat))
        warn("%s terminated abnormally", promptprog);
-    if (WEXITSTATUS(wstat))
-       warn("%s exited with code %d", promptprog, WEXITSTATUS(status));
-
+    if (WEXITSTATUS(wstat)) {
+           warn("%s exited with code %d", promptprog, WEXITSTATUS(wstat));
+           /* code when cancel was hit in the prompt prog */
+           if (WEXITSTATUS(wstat) == 128) {
+               promptprog_refused = 1;
+           }
+           return -1;
+    }
     return 1;
 }
 
@@ -107,4 +122,7 @@ void plugin_init(void)
 {
     add_options(options);
     pap_passwd_hook = promptpass;
+#ifdef PPP_WITH_EAPTLS
+    eaptls_passwd_hook = promptpass;
+#endif
 }