18ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* 28ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * passprompt.c - pppd plugin to invoke an external PAP password prompter 38ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 48ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Copyright 1999 Paul Mackerras, Alan Curry. 58ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 68ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * This program is free software; you can redistribute it and/or 78ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * modify it under the terms of the GNU General Public License 88ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * as published by the Free Software Foundation; either version 98ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 2 of the License, or (at your option) any later version. 108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <errno.h> 128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <unistd.h> 138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <sys/wait.h> 148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <syslog.h> 158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "pppd.h" 168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectchar pppd_version[] = VERSION; 188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic char promptprog[PATH_MAX+1]; 208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic option_t options[] = { 228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { "promptprog", o_string, promptprog, 238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project "External PAP password prompting program", 248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project OPT_STATIC, NULL, PATH_MAX }, 258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { NULL } 268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}; 278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int promptpass(char *user, char *passwd) 298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int p[2]; 318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project pid_t kid; 328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int readgood, wstat; 338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ssize_t red; 348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (promptprog[0] == 0 || access(promptprog, X_OK) < 0) 368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return -1; /* sorry, can't help */ 378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (!passwd) 398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return 1; 408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (pipe(p)) { 428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project warn("Can't make a pipe for %s", promptprog); 438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return 0; 448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if ((kid = fork()) == (pid_t) -1) { 468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project warn("Can't fork to run %s", promptprog); 478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project close(p[0]); 488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project close(p[1]); 498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return 0; 508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (!kid) { 528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* we are the child, exec the program */ 531286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley char *argv[5], fdstr[32]; 548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sys_close(); 558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project closelog(); 568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project close(p[0]); 578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project seteuid(getuid()); 588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project setegid(getgid()); 598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project argv[0] = promptprog; 608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project argv[1] = user; 618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project argv[2] = remote_name; 628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sprintf(fdstr, "%d", p[1]); 638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project argv[3] = fdstr; 648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project argv[4] = 0; 658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project execv(*argv, argv); 668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project _exit(127); 678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* we are the parent, read the password from the pipe */ 708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project close(p[1]); 718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project readgood = 0; 728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project do { 738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project red = read(p[0], passwd + readgood, MAXSECRETLEN-1 - readgood); 748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (red == 0) 758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project break; 768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (red < 0) { 778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (errno == EINTR) 788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project continue; 798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project error("Can't read secret from %s: %m", promptprog); 808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project readgood = -1; 818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project break; 828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project readgood += red; 848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } while (readgood < MAXSECRETLEN - 1); 858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project close(p[0]); 868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* now wait for child to exit */ 888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project while (waitpid(kid, &wstat, 0) < 0) { 898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (errno != EINTR) { 908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project warn("error waiting for %s: %m", promptprog); 918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project break; 928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (readgood < 0) 968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return 0; 971286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley passwd[readgood] = 0; 988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (!WIFEXITED(wstat)) 998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project warn("%s terminated abnormally", promptprog); 1008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (WEXITSTATUS(wstat)) 1018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project warn("%s exited with code %d", promptprog, WEXITSTATUS(status)); 1028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return 1; 1048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 1058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid plugin_init(void) 1078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 1088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project add_options(options); 1098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project pap_passwd_hook = promptpass; 1108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 111