aboutsummaryrefslogtreecommitdiff
path: root/patches/0016-doas-Port-to-linux-musl.patch
diff options
context:
space:
mode:
Diffstat (limited to 'patches/0016-doas-Port-to-linux-musl.patch')
-rw-r--r--patches/0016-doas-Port-to-linux-musl.patch435
1 files changed, 0 insertions, 435 deletions
diff --git a/patches/0016-doas-Port-to-linux-musl.patch b/patches/0016-doas-Port-to-linux-musl.patch
deleted file mode 100644
index 877d3f0..0000000
--- a/patches/0016-doas-Port-to-linux-musl.patch
+++ /dev/null
@@ -1,435 +0,0 @@
-From c95443d87b64650823e41016c26b1f5a3b38e7b3 Mon Sep 17 00:00:00 2001
-From: Michael Forney <mforney@mforney.org>
-Date: Sun, 26 Feb 2017 16:50:55 -0800
-Subject: [PATCH] doas: Port to linux/musl
-
-Remove -a login style option and BSD authentication. Instead, compare
-against shadow file.
-
-Use timestamp files in /run/doas instead of TIOC*VERAUTH to implement
-persist.
-
-Use initgroups/setgid/setuid instead of setusercontext.
-
-Provide UID_MAX and GID_MAX defaults.
-
-Use LOGIN_NAME_MAX instead of _PW_NAME_LEN.
-
-Remove call to closefrom.
-
-Replace calls to errc with err after setting errno.
-
-Call openlog at start to set syslog identity.
----
- usr.bin/doas/doas.1 | 9 ---
- usr.bin/doas/doas.c | 97 ++++++++++++++++--------------
- usr.bin/doas/doas.h | 4 ++
- usr.bin/doas/parse.y | 1 +
- usr.bin/doas/persist.c | 133 +++++++++++++++++++++++++++++++++++++++++
- 5 files changed, 191 insertions(+), 53 deletions(-)
- create mode 100644 usr.bin/doas/persist.c
-
-diff --git a/usr.bin/doas/doas.1 b/usr.bin/doas/doas.1
-index fc769bdb336..c7196e347a9 100644
---- a/usr.bin/doas/doas.1
-+++ b/usr.bin/doas/doas.1
-@@ -22,7 +22,6 @@
- .Sh SYNOPSIS
- .Nm doas
- .Op Fl Lns
--.Op Fl a Ar style
- .Op Fl C Ar config
- .Op Fl u Ar user
- .Ar command
-@@ -67,14 +66,6 @@ The working directory is not changed.
- .Pp
- The options are as follows:
- .Bl -tag -width tenletters
--.It Fl a Ar style
--Use the specified authentication style when validating the user,
--as allowed by
--.Pa /etc/login.conf .
--A list of doas-specific authentication methods may be configured by adding an
--.Sq auth-doas
--entry in
--.Xr login.conf 5 .
- .It Fl C Ar config
- Parse and check the configuration file
- .Ar config ,
-diff --git a/usr.bin/doas/doas.c b/usr.bin/doas/doas.c
-index a723c67a3eb..e7e3e639401 100644
---- a/usr.bin/doas/doas.c
-+++ b/usr.bin/doas/doas.c
-@@ -20,8 +20,6 @@
- #include <sys/ioctl.h>
-
- #include <limits.h>
--#include <login_cap.h>
--#include <bsd_auth.h>
- #include <readpassphrase.h>
- #include <string.h>
- #include <stdio.h>
-@@ -33,13 +31,22 @@
- #include <syslog.h>
- #include <errno.h>
- #include <fcntl.h>
-+#include <shadow.h>
-
- #include "doas.h"
-
-+#ifndef UID_MAX
-+#define UID_MAX 65535
-+#endif
-+
-+#ifndef GID_MAX
-+#define GID_MAX 65535
-+#endif
-+
- static void __dead
- usage(void)
- {
-- fprintf(stderr, "usage: doas [-Lns] [-a style] [-C config] [-u user]"
-+ fprintf(stderr, "usage: doas [-Lns] [-C config] [-u user]"
- " command [args]\n");
- exit(1);
- }
-@@ -197,23 +204,36 @@ checkconfig(const char *confpath, int argc, char **argv,
- }
- }
-
-+static int
-+verifypasswd(const char *user, const char *pass)
-+{
-+ struct spwd *sp;
-+ char *p1, *p2;
-+
-+ sp = getspnam(user);
-+ if (!sp)
-+ return 0;
-+ p1 = sp->sp_pwdp;
-+ if (p1[0] == '!' || p1[0] == '*')
-+ return 0;
-+ p2 = crypt(pass, p1);
-+ if (!p2)
-+ return 0;
-+ return strcmp(p1, p2) == 0;
-+}
-+
- static void
--authuser(char *myname, char *login_style, int persist)
-+authuser(char *myname, int persist)
- {
- char *challenge = NULL, *response, rbuf[1024], cbuf[128];
-- auth_session_t *as;
-- int fd = -1;
-+ int fd = -1, valid = 0;
-
-- if (persist)
-- fd = open("/dev/tty", O_RDWR);
-- if (fd != -1) {
-- if (ioctl(fd, TIOCCHKVERAUTH) == 0)
-+ if (persist) {
-+ fd = openpersist(&valid);
-+ if (valid)
- goto good;
- }
-
-- if (!(as = auth_userchallenge(myname, login_style, "auth-doas",
-- &challenge)))
-- errx(1, "Authorization failed");
- if (!challenge) {
- char host[HOST_NAME_MAX + 1];
- if (gethostname(host, sizeof(host)))
-@@ -225,21 +245,18 @@ authuser(char *myname, char *login_style, int persist)
- response = readpassphrase(challenge, rbuf, sizeof(rbuf),
- RPP_REQUIRE_TTY);
- if (response == NULL && errno == ENOTTY) {
-- syslog(LOG_AUTHPRIV | LOG_NOTICE,
-- "tty required for %s", myname);
-+ syslog(LOG_NOTICE, "tty required for %s", myname);
- errx(1, "a tty is required");
- }
-- if (!auth_userresponse(as, response, 0)) {
-+ if (!verifypasswd(myname, response)) {
- explicit_bzero(rbuf, sizeof(rbuf));
-- syslog(LOG_AUTHPRIV | LOG_NOTICE,
-- "failed auth for %s", myname);
-+ syslog(LOG_NOTICE, "failed auth for %s", myname);
- errx(1, "Authorization failed");
- }
- explicit_bzero(rbuf, sizeof(rbuf));
- good:
- if (fd != -1) {
-- int secs = 5 * 60;
-- ioctl(fd, TIOCSETVERAUTH, &secs);
-+ setpersist(fd);
- close(fd);
- }
- }
-@@ -285,15 +302,14 @@ done:
- int
- main(int argc, char **argv)
- {
-- const char *safepath = "/bin:/sbin:/usr/bin:/usr/sbin:"
-- "/usr/local/bin:/usr/local/sbin";
-+ const char *safepath = "/bin";
- const char *confpath = NULL;
- char *shargv[] = { NULL, NULL };
- char *sh;
- const char *p;
- const char *cmd;
- char cmdline[LINE_MAX];
-- char mypwbuf[_PW_BUF_LEN], targpwbuf[_PW_BUF_LEN];
-+ char mypwbuf[1024], targpwbuf[1024];
- struct passwd mypwstore, targpwstore;
- struct passwd *mypw, *targpw;
- const struct rule *rule;
-@@ -306,28 +322,20 @@ main(int argc, char **argv)
- int nflag = 0;
- char cwdpath[PATH_MAX];
- const char *cwd;
-- char *login_style = NULL;
- char **envp;
-
- setprogname("doas");
--
-- closefrom(STDERR_FILENO + 1);
-+ openlog("doas", 0, LOG_AUTHPRIV);
-
- uid = getuid();
-
-- while ((ch = getopt(argc, argv, "a:C:Lnsu:")) != -1) {
-+ while ((ch = getopt(argc, argv, "C:Lnsu:")) != -1) {
- switch (ch) {
-- case 'a':
-- login_style = optarg;
-- break;
- case 'C':
- confpath = optarg;
- break;
- case 'L':
-- i = open("/dev/tty", O_RDWR);
-- if (i != -1)
-- ioctl(i, TIOCCLRVERAUTH);
-- exit(i == -1);
-+ exit(clearpersist() != 0);
- case 'u':
- if (parseuid(optarg, &target) != 0)
- errx(1, "unknown user");
-@@ -395,16 +403,16 @@ main(int argc, char **argv)
- cmd = argv[0];
- if (!permit(uid, groups, ngroups, &rule, target, cmd,
- (const char **)argv + 1)) {
-- syslog(LOG_AUTHPRIV | LOG_NOTICE,
-- "failed command for %s: %s", mypw->pw_name, cmdline);
-- errc(1, EPERM, NULL);
-+ syslog(LOG_NOTICE, "failed command for %s: %s", mypw->pw_name, cmdline);
-+ errno = EPERM;
-+ err(1, NULL);
- }
-
- if (!(rule->options & NOPASS)) {
- if (nflag)
- errx(1, "Authorization required");
-
-- authuser(mypw->pw_name, login_style, rule->options & PERSIST);
-+ authuser(mypw->pw_name, rule->options & PERSIST);
- }
-
- if ((p = getenv("PATH")) != NULL)
-@@ -431,11 +439,12 @@ main(int argc, char **argv)
- if (targpw == NULL)
- errx(1, "no passwd entry for target");
-
-- if (setusercontext(NULL, targpw, target, LOGIN_SETGROUP |
-- LOGIN_SETPATH |
-- LOGIN_SETPRIORITY | LOGIN_SETRESOURCES | LOGIN_SETUMASK |
-- LOGIN_SETUSER) != 0)
-- errx(1, "failed to set user context for target");
-+ if (initgroups(targpw->pw_name, targpw->pw_gid) < 0)
-+ err(1, "initgroups");
-+ if (setgid(targpw->pw_gid) < 0)
-+ err(1, "setgid");
-+ if (setuid(targpw->pw_uid) < 0)
-+ err(1, "setuid");
-
- if (pledge("stdio rpath exec", NULL) == -1)
- err(1, "pledge");
-@@ -448,7 +457,7 @@ main(int argc, char **argv)
- if (pledge("stdio exec", NULL) == -1)
- err(1, "pledge");
-
-- syslog(LOG_AUTHPRIV | LOG_INFO, "%s ran command %s as %s from %s",
-+ syslog(LOG_INFO, "%s ran command %s as %s from %s",
- mypw->pw_name, cmdline, targpw->pw_name, cwd);
-
- envp = prepenv(rule, mypw, targpw);
-diff --git a/usr.bin/doas/doas.h b/usr.bin/doas/doas.h
-index 6f50fc22869..c97986e3cf3 100644
---- a/usr.bin/doas/doas.h
-+++ b/usr.bin/doas/doas.h
-@@ -36,6 +36,10 @@ struct passwd;
- char **prepenv(const struct rule *, const struct passwd *,
- const struct passwd *);
-
-+int openpersist(int *valid);
-+int setpersist(int fd);
-+int clearpersist(void);
-+
- #define PERMIT 1
- #define DENY 2
-
-diff --git a/usr.bin/doas/parse.y b/usr.bin/doas/parse.y
-index dd9466e5f13..d1f698c7679 100644
---- a/usr.bin/doas/parse.y
-+++ b/usr.bin/doas/parse.y
-@@ -19,6 +19,7 @@
- #include <sys/types.h>
- #include <ctype.h>
- #include <unistd.h>
-+#include <stdlib.h>
- #include <stdint.h>
- #include <stdarg.h>
- #include <stdio.h>
-diff --git a/usr.bin/doas/persist.c b/usr.bin/doas/persist.c
-new file mode 100644
-index 00000000000..4ad1bf1efbf
---- /dev/null
-+++ b/usr.bin/doas/persist.c
-@@ -0,0 +1,133 @@
-+#include <errno.h>
-+#include <fcntl.h>
-+#include <limits.h>
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <string.h>
-+#include <sys/stat.h>
-+#include <sys/types.h>
-+#include <time.h>
-+#include <unistd.h>
-+
-+#include "doas.h"
-+
-+#define PERSIST_DIR "/run/doas"
-+#define PERSIST_TIMEOUT 5 * 60
-+
-+static int
-+ttyid(dev_t *tty)
-+{
-+ int fd, i;
-+ char buf[BUFSIZ], *p;
-+ ssize_t n;
-+
-+ fd = open("/proc/self/stat", O_RDONLY);
-+ if (fd == -1)
-+ return -1;
-+ n = read(fd, buf, sizeof(buf) - 1);
-+ if (n >= 0)
-+ buf[n] = '\0';
-+ /* check that we read the whole file */
-+ n = read(fd, buf, 1);
-+ close(fd);
-+ if (n != 0)
-+ return -1;
-+ p = strrchr(buf, ')');
-+ if (!p)
-+ return -1;
-+ ++p;
-+ /* ttr_nr is the 5th field after executable name, so skip the next 4 */
-+ for (i = 0; i < 4; ++i) {
-+ p = strchr(++p, ' ');
-+ if (!p)
-+ return -1;
-+ }
-+ *tty = strtol(p, &p, 10);
-+ if (*p != ' ')
-+ return -1;
-+ return 0;
-+}
-+
-+static int
-+persistpath(char *buf, size_t len)
-+{
-+ dev_t tty;
-+ int n;
-+
-+ if (ttyid(&tty) < 0)
-+ return -1;
-+ n = snprintf(buf, len, PERSIST_DIR "/%ju-%ju", (uintmax_t)getuid(), (uintmax_t)tty);
-+ if (n < 0 || n >= (int)len)
-+ return -1;
-+ return 0;
-+}
-+
-+int
-+openpersist(int *valid)
-+{
-+ char path[256];
-+ struct stat st;
-+ struct timespec ts;
-+ int fd;
-+
-+ if (stat(PERSIST_DIR, &st) < 0) {
-+ if (errno != ENOENT)
-+ return -1;
-+ if (mkdir(PERSIST_DIR, 0700) < 0)
-+ return -1;
-+ } else if (st.st_uid != 0 || st.st_mode != (S_IFDIR | 0700)) {
-+ return -1;
-+ }
-+ if (persistpath(path, sizeof(path)) < 0)
-+ return -1;
-+ fd = open(path, O_RDONLY);
-+ if (fd == -1) {
-+ char tmp[256];
-+ struct timespec ts[2] = { { .tv_nsec = UTIME_OMIT }, { 0 } };
-+ int n;
-+
-+ n = snprintf(tmp, sizeof(tmp), PERSIST_DIR "/.tmp-%d", getpid());
-+ if (n < 0 || n >= (int)sizeof(tmp))
-+ return -1;
-+ fd = open(tmp, O_RDONLY | O_CREAT | O_EXCL, 0);
-+ if (fd == -1)
-+ return -1;
-+ if (futimens(fd, ts) < 0 || rename(tmp, path) < 0) {
-+ close(fd);
-+ unlink(tmp);
-+ return -1;
-+ }
-+ *valid = 0;
-+ } else {
-+ *valid = clock_gettime(CLOCK_BOOTTIME, &ts) == 0 &&
-+ fstat(fd, &st) == 0 &&
-+ (ts.tv_sec < st.st_mtim.tv_sec ||
-+ (ts.tv_sec == st.st_mtim.tv_sec && ts.tv_nsec < st.st_mtim.tv_nsec)) &&
-+ st.st_mtime - ts.tv_sec <= PERSIST_TIMEOUT;
-+ }
-+ return fd;
-+}
-+
-+int
-+setpersist(int fd)
-+{
-+ struct timespec times[2];
-+
-+ if (clock_gettime(CLOCK_BOOTTIME, &times[1]) < 0)
-+ return -1;
-+ times[0].tv_nsec = UTIME_OMIT;
-+ times[1].tv_sec += PERSIST_TIMEOUT;
-+ return futimens(fd, times);
-+}
-+
-+int
-+clearpersist(void)
-+{
-+ char path[256];
-+
-+ if (persistpath(path, sizeof(path)) < 0)
-+ return -1;
-+ if (unlink(path) < 0 && errno != ENOENT)
-+ return -1;
-+ return 0;
-+}
---
-2.27.0
-