int auth_Validate(struct bundle *bundle, const char *name, const char *key, struct physical *physical) { /* Used by PAP routines */ FILE *fp; int n, lineno; char *vector[5], buff[LINE_LEN]; const char *slash; fp = OpenSecret(SECRETFILE); again: lineno = 0; if (fp != NULL) { while (fgets(buff, sizeof buff, fp)) { lineno++; if (buff[0] == '#') continue; buff[strcspn(buff, "\n")] = '\0'; memset(vector, '\0', sizeof vector); if ((n = MakeArgs(buff, vector, VECSIZE(vector), PARSE_REDUCE)) < 0) log_Printf(LogWARN, "%s: %d: Invalid line\n", SECRETFILE, lineno); if (n < 2) continue; if (strcmp(vector[0], name) == 0) { CloseSecret(fp); return auth_CheckPasswd(name, vector[1], key); } } } if ((slash = strrchr(name, '\\')) != NULL && slash[1]) { /* Look for the name without the leading domain */ name = slash + 1; if (fp != NULL) { rewind(fp); goto again; } } if (fp != NULL) CloseSecret(fp); #ifndef NOPASSWDAUTH if (Enabled(bundle, OPT_PASSWDAUTH)) return auth_CheckPasswd(name, "*", key); #endif return 0; /* Invalid */ }
char * auth_GetSecret(struct bundle *bundle, const char *name, int len, struct physical *physical) { /* Used by CHAP routines */ FILE *fp; int n, lineno; char *vector[5]; const char *slash; static char buff[LINE_LEN]; /* vector[] will point here when returned */ fp = OpenSecret(SECRETFILE); if (fp == NULL) return (NULL); again: lineno = 0; while (fgets(buff, sizeof buff, fp)) { lineno++; if (buff[0] == '#') continue; n = strlen(buff) - 1; if (buff[n] == '\n') buff[n] = '\0'; /* Trim the '\n' */ memset(vector, '\0', sizeof vector); if ((n = MakeArgs(buff, vector, VECSIZE(vector), PARSE_REDUCE)) < 0) log_Printf(LogWARN, "%s: %d: Invalid line\n", SECRETFILE, lineno); if (n < 2) continue; if (strlen(vector[0]) == len && strncmp(vector[0], name, len) == 0) { CloseSecret(fp); return vector[1]; } } if ((slash = strrchr(name, '\\')) != NULL && slash[1]) { /* Go back and look for the name without the leading domain */ len -= slash - name + 1; name = slash + 1; rewind(fp); goto again; } CloseSecret(fp); return (NULL); /* Invalid */ }
int auth_SetPhoneList(const char *name, char *phone, int phonelen) { FILE *fp; int n, lineno; char *vector[6], buff[LINE_LEN]; const char *slash; fp = OpenSecret(SECRETFILE); if (fp != NULL) { again: lineno = 0; while (fgets(buff, sizeof buff, fp)) { lineno++; if (buff[0] == '#') continue; buff[strlen(buff) - 1] = '\0'; memset(vector, '\0', sizeof vector); if ((n = MakeArgs(buff, vector, VECSIZE(vector), PARSE_REDUCE)) < 0) log_Printf(LogWARN, "%s: %d: Invalid line\n", SECRETFILE, lineno); if (n < 5) continue; if (strcmp(vector[0], name) == 0) { CloseSecret(fp); if (*vector[4] == '\0') return 0; strncpy(phone, vector[4], phonelen - 1); phone[phonelen - 1] = '\0'; return 1; /* Valid */ } } if ((slash = strrchr(name, '\\')) != NULL && slash[1]) { /* Look for the name without the leading domain */ name = slash + 1; rewind(fp); goto again; } CloseSecret(fp); } *phone = '\0'; return 0; }
static char * GetLabel(char *line, const char *filename, int linenum) { char *argv[MAXARGS]; int argc, len; argc = MakeArgs(line, argv, MAXARGS, PARSE_REDUCE); if (argc == 2 && !strcmp(argv[1], ":")) return argv[0]; if (argc != 1 || (len = strlen(argv[0])) < 2 || argv[0][len-1] != ':') { log_Printf(LogWARN, "Bad label in %s (line %d) - missing colon\n", filename, linenum); return NULL; } argv[0][len-1] = '\0'; /* Lose the ':' */ return argv[0]; }
int auth_Select(struct bundle *bundle, const char *name) { FILE *fp; int n, lineno; char *vector[5], buff[LINE_LEN]; const char *slash; if (*name == '\0') { ipcp_Setup(&bundle->ncp.ipcp, INADDR_NONE); return 1; } #ifndef NORADIUS if (bundle->radius.valid && bundle->radius.ip.s_addr != INADDR_NONE && bundle->radius.ip.s_addr != RADIUS_INADDR_POOL) { /* We've got a radius IP - it overrides everything */ if (!ipcp_UseHisIPaddr(bundle, bundle->radius.ip)) return 0; ipcp_Setup(&bundle->ncp.ipcp, bundle->radius.mask.s_addr); /* Continue with ppp.secret in case we've got a new label */ } #endif fp = OpenSecret(SECRETFILE); if (fp != NULL) { again: lineno = 0; while (fgets(buff, sizeof buff, fp)) { lineno++; if (buff[0] == '#') continue; buff[strlen(buff) - 1] = '\0'; memset(vector, '\0', sizeof vector); if ((n = MakeArgs(buff, vector, VECSIZE(vector), PARSE_REDUCE)) < 0) log_Printf(LogWARN, "%s: %d: Invalid line\n", SECRETFILE, lineno); if (n < 2) continue; if (strcmp(vector[0], name) == 0) { CloseSecret(fp); #ifndef NORADIUS if (!bundle->radius.valid || bundle->radius.ip.s_addr == INADDR_NONE) { #endif if (n > 2 && *vector[2] && strcmp(vector[2], "*") && !ipcp_UseHisaddr(bundle, vector[2], 1)) return 0; ipcp_Setup(&bundle->ncp.ipcp, INADDR_NONE); #ifndef NORADIUS } #endif if (n > 3 && *vector[3] && strcmp(vector[3], "*")) bundle_SetLabel(bundle, vector[3]); return 1; /* Valid */ } } if ((slash = strrchr(name, '\\')) != NULL && slash[1]) { /* Look for the name without the leading domain */ name = slash + 1; rewind(fp); goto again; } CloseSecret(fp); } #ifndef NOPASSWDAUTH /* Let 'em in anyway - they must have been in the passwd file */ ipcp_Setup(&bundle->ncp.ipcp, INADDR_NONE); return 1; #else #ifndef NORADIUS if (bundle->radius.valid) return 1; #endif /* Disappeared from ppp.secret ??? */ return 0; #endif }
struct device * exec_Create(struct physical *p) { struct execdevice *dev; dev = NULL; if (p->fd < 0) { if (*p->name.full == '!') { int fids[2], type; if ((dev = malloc(sizeof *dev)) == NULL) { log_Printf(LogWARN, "%s: Cannot allocate an exec device: %s\n", p->link.name, strerror(errno)); return NULL; } dev->fd_out = -1; p->fd--; /* We own the device but maybe can't use it - change fd */ type = physical_IsSync(p) ? SOCK_DGRAM : SOCK_STREAM; if (socketpair(AF_UNIX, type, PF_UNSPEC, fids) < 0) { log_Printf(LogPHASE, "Unable to create pipe for line exec: %s\n", strerror(errno)); free(dev); dev = NULL; } else { static int child_status; /* This variable is abused ! */ int stat, argc, i, ret, wret, pidpipe[2]; pid_t pid, realpid; char *argv[MAXARGS]; stat = fcntl(fids[0], F_GETFL, 0); if (stat > 0) { stat |= O_NONBLOCK; fcntl(fids[0], F_SETFL, stat); } realpid = getpid(); if (pipe(pidpipe) == -1) { log_Printf(LogPHASE, "Unable to pipe for line exec: %s\n", strerror(errno)); close(fids[1]); close(fids[0]); free(dev); dev = NULL; } else switch ((pid = fork())) { case -1: log_Printf(LogPHASE, "Unable to fork for line exec: %s\n", strerror(errno)); close(pidpipe[0]); close(pidpipe[1]); close(fids[1]); close(fids[0]); break; case 0: close(pidpipe[0]); close(fids[0]); timer_TermService(); #ifndef NOSUID setuid(ID0realuid()); #endif child_status = 0; switch ((pid = vfork())) { case 0: close(pidpipe[1]); break; case -1: ret = errno; log_Printf(LogPHASE, "Unable to vfork to drop parent: %s\n", strerror(errno)); close(pidpipe[1]); _exit(ret); default: write(pidpipe[1], &pid, sizeof pid); close(pidpipe[1]); _exit(child_status); /* The error from exec() ! */ } log_Printf(LogDEBUG, "Exec'ing ``%s''\n", p->name.base); if ((argc = MakeArgs(p->name.base, argv, VECSIZE(argv), PARSE_REDUCE|PARSE_NOHASH)) < 0) { log_Printf(LogWARN, "Syntax error in exec command\n"); _exit(ESRCH); } command_Expand(argv, argc, (char const *const *)argv, p->dl->bundle, 0, realpid); dup2(fids[1], STDIN_FILENO); dup2(fids[1], STDOUT_FILENO); dup2(fids[1], STDERR_FILENO); for (i = getdtablesize(); i > STDERR_FILENO; i--) fcntl(i, F_SETFD, 1); execvp(*argv, argv); child_status = errno; /* Only works for vfork() */ printf("execvp failed: %s: %s\r\n", *argv, strerror(child_status)); _exit(child_status); break; default: close(pidpipe[1]); close(fids[1]); if (read(pidpipe[0], &p->session_owner, sizeof p->session_owner) != sizeof p->session_owner) p->session_owner = (pid_t)-1; close(pidpipe[0]); while ((wret = waitpid(pid, &stat, 0)) == -1 && errno == EINTR) ; if (wret == -1) { log_Printf(LogWARN, "Waiting for child process: %s\n", strerror(errno)); close(fids[0]); p->session_owner = (pid_t)-1; break; } else if (WIFSIGNALED(stat)) { log_Printf(LogWARN, "Child process received sig %d !\n", WTERMSIG(stat)); close(fids[0]); p->session_owner = (pid_t)-1; break; } else if (WIFSTOPPED(stat)) { log_Printf(LogWARN, "Child process received stop sig %d !\n", WSTOPSIG(stat)); /* I guess that's ok.... */ } else if ((ret = WEXITSTATUS(stat))) { log_Printf(LogWARN, "Cannot exec \"%s\": %s\n", p->name.base, strerror(ret)); close(fids[0]); p->session_owner = (pid_t)-1; break; } p->fd = fids[0]; log_Printf(LogDEBUG, "Using descriptor %d for child\n", p->fd); } } } } else { struct stat st; if (fstat(p->fd, &st) != -1 && (st.st_mode & S_IFIFO)) { if ((dev = malloc(sizeof *dev)) == NULL) log_Printf(LogWARN, "%s: Cannot allocate an exec device: %s\n", p->link.name, strerror(errno)); else if (p->fd == STDIN_FILENO) { log_Printf(LogPHASE, "%s: Using stdin/stdout to communicate with " "parent (pipe mode)\n", p->link.name); dev->fd_out = dup(STDOUT_FILENO); /* Hook things up so that we monitor dev->fd_out */ p->desc.UpdateSet = exec_UpdateSet; p->desc.IsSet = exec_IsSet; } else dev->fd_out = -1; } } if (dev) { memcpy(&dev->dev, &baseexecdevice, sizeof dev->dev); physical_SetupStack(p, dev->dev.name, PHYSICAL_NOFORCE); if (p->cfg.cd.necessity != CD_DEFAULT) log_Printf(LogWARN, "Carrier settings ignored\n"); return &dev->dev; } return NULL; }