diff options
Diffstat (limited to 'contrib/pf/authpf/authpf.c')
-rw-r--r-- | contrib/pf/authpf/authpf.c | 104 |
1 files changed, 54 insertions, 50 deletions
diff --git a/contrib/pf/authpf/authpf.c b/contrib/pf/authpf/authpf.c index 1ae6aa4..68adcd2 100644 --- a/contrib/pf/authpf/authpf.c +++ b/contrib/pf/authpf/authpf.c @@ -1,28 +1,19 @@ -/* $OpenBSD: authpf.c,v 1.89 2005/02/10 04:24:15 joel Exp $ */ +/* $OpenBSD: authpf.c,v 1.104 2007/02/24 17:35:08 beck Exp $ */ /* - * Copyright (C) 1998 - 2002 Bob Beck (beck@openbsd.org). + * Copyright (C) 1998 - 2007 Bob Beck (beck@openbsd.org). * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include <sys/types.h> @@ -50,15 +41,13 @@ #include "pathnames.h" -extern int symset(const char *, const char *, int); - static int read_config(FILE *); static void print_message(char *); static int allowed_luser(char *); static int check_luser(char *, char *); static int remove_stale_rulesets(void); static int change_filter(int, const char *, const char *); -static int change_table(int, const char *, const char *); +static int change_table(int, const char *); static void authpf_kill_states(void); int dev; /* pf device */ @@ -67,7 +56,6 @@ char rulesetname[MAXPATHLEN - PF_ANCHOR_NAME_SIZE - 2]; char tablename[PF_TABLE_NAME_SIZE] = "authpf_users"; FILE *pidfp; -char *infile; /* file name printed by yyerror() in parse.y */ char luser[MAXLOGNAME]; /* username */ char ipsrc[256]; /* ip as a string */ char pidfile[MAXPATHLEN]; /* we save pid in this file. */ @@ -92,11 +80,16 @@ main(int argc, char *argv[]) struct in6_addr ina; struct passwd *pw; char *cp; + gid_t gid; uid_t uid; char *shell; login_cap_t *lc; config = fopen(PATH_CONFFILE, "r"); + if (config == NULL) { + syslog(LOG_ERR, "can not open %s (%m)", PATH_CONFFILE); + exit(1); + } if ((cp = getenv("SSH_TTY")) == NULL) { syslog(LOG_ERR, "non-interactive session connection for authpf"); @@ -133,7 +126,6 @@ main(int argc, char *argv[]) uid = getuid(); pw = getpwuid(uid); - endpwent(); if (pw == NULL) { syslog(LOG_ERR, "cannot find user for uid %u", uid); goto die; @@ -246,6 +238,8 @@ main(int argc, char *argv[]) if (++lockcnt > 10) { syslog(LOG_ERR, "cannot kill previous authpf (pid %d)", otherpid); + fclose(pidfp); + pidfp = NULL; goto dogdeath; } sleep(1); @@ -255,12 +249,22 @@ main(int argc, char *argv[]) * it's lock, giving us a chance to get it now */ fclose(pidfp); + pidfp = NULL; } while (1); + + /* whack the group list */ + gid = getegid(); + if (setgroups(1, &gid) == -1) { + syslog(LOG_INFO, "setgroups: %s", strerror(errno)); + do_death(0); + } /* revoke privs */ - seteuid(getuid()); - setuid(getuid()); - + uid = getuid(); + if (setresuid(uid, uid, uid) == -1) { + syslog(LOG_INFO, "setresuid: %s", strerror(errno)); + do_death(0); + } openlog("authpf", LOG_PID | LOG_NDELAY, LOG_DAEMON); if (!check_luser(PATH_BAN_DIR, luser) || !allowed_luser(luser)) { @@ -268,8 +272,8 @@ main(int argc, char *argv[]) do_death(0); } - if (config == NULL || read_config(config)) { - syslog(LOG_INFO, "bad or nonexistent %s", PATH_CONFFILE); + if (read_config(config)) { + syslog(LOG_ERR, "invalid config file %s", PATH_CONFFILE); do_death(0); } @@ -288,7 +292,7 @@ main(int argc, char *argv[]) printf("Unable to modify filters\r\n"); do_death(0); } - if (change_table(1, luser, ipsrc) == -1) { + if (change_table(1, ipsrc) == -1) { printf("Unable to modify table\r\n"); change_filter(0, luser, ipsrc); do_death(0); @@ -299,7 +303,7 @@ main(int argc, char *argv[]) signal(SIGALRM, need_death); signal(SIGPIPE, need_death); signal(SIGHUP, need_death); - signal(SIGSTOP, need_death); + signal(SIGQUIT, need_death); signal(SIGTSTP, need_death); while (1) { printf("\r\nHello %s. ", luser); @@ -547,9 +551,11 @@ check_luser(char *luserdir, char *luser) while (fputs(tmp, stdout) != EOF && !feof(f)) { if (fgets(tmp, sizeof(tmp), f) == NULL) { fflush(stdout); + fclose(f); return (0); } } + fclose(f); } fflush(stdout); return (0); @@ -633,6 +639,7 @@ change_filter(int add, const char *luser, const char *ipsrc) char *fdpath = NULL, *userstr = NULL, *ipstr = NULL; char *rsn = NULL, *fn = NULL; pid_t pid; + gid_t gid; int s; if (luser == NULL || !luser[0] || ipsrc == NULL || !ipsrc[0]) { @@ -672,8 +679,14 @@ change_filter(int add, const char *luser, const char *ipsrc) switch (pid = fork()) { case -1: - err(1, "fork failed"); + syslog(LOG_ERR, "fork failed"); + goto error; case 0: + /* revoke group privs before exec */ + gid = getgid(); + if (setregid(gid, gid) == -1) { + err(1, "setregid"); + } execvp(PATH_PFCTL, pargv); warn("exec of %s failed", PATH_PFCTL); _exit(1); @@ -682,10 +695,8 @@ change_filter(int add, const char *luser, const char *ipsrc) /* parent */ waitpid(pid, &s, 0); if (s != 0) { - if (WIFEXITED(s)) { - syslog(LOG_ERR, "pfctl exited abnormally"); - goto error; - } + syslog(LOG_ERR, "pfctl exited abnormally"); + goto error; } if (add) { @@ -701,16 +712,10 @@ no_mem: syslog(LOG_ERR, "malloc failed"); error: free(fdpath); - fdpath = NULL; free(rsn); - rsn = NULL; free(userstr); - userstr = NULL; free(ipstr); - ipstr = NULL; free(fn); - fn = NULL; - infile = NULL; return (-1); } @@ -718,13 +723,14 @@ error: * Add/remove this IP from the "authpf_users" table. */ static int -change_table(int add, const char *luser, const char *ipsrc) +change_table(int add, const char *ipsrc) { struct pfioc_table io; struct pfr_addr addr; bzero(&io, sizeof(io)); - strlcpy(io.pfrio_table.pfrt_name, tablename, sizeof(io.pfrio_table)); + strlcpy(io.pfrio_table.pfrt_name, tablename, + sizeof(io.pfrio_table.pfrt_name)); io.pfrio_buffer = &addr; io.pfrio_esize = sizeof(addr); io.pfrio_size = 1; @@ -813,13 +819,11 @@ do_death(int active) if (active) { change_filter(0, luser, ipsrc); - change_table(0, luser, ipsrc); + change_table(0, ipsrc); authpf_kill_states(); remove_stale_rulesets(); } - if (pidfp) - ftruncate(fileno(pidfp), 0); - if (pidfile[0]) + if (pidfile[0] && (pidfp != NULL)) if (unlink(pidfile) == -1) syslog(LOG_ERR, "cannot unlink %s (%m)", pidfile); exit(ret); |