aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorlns <matzeton@googlemail.com>2018-07-19 22:00:12 +0200
committerlns <matzeton@googlemail.com>2018-07-19 22:00:12 +0200
commit169fc69a9d0f3b213fabf57e4d9b49bd3eacdc76 (patch)
tree7f90832ac63cfc1ca5929ff2df00a5f97f692b7e /src
parent0a582bc2086e98302f7da2a2e6b128cca6d3b444 (diff)
added compat module and functions
Signed-off-by: lns <matzeton@googlemail.com>
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am2
-rw-r--r--src/compat.c104
-rw-r--r--src/compat.h55
-rw-r--r--src/filesystem.c11
-rw-r--r--src/log.c7
-rw-r--r--src/main.c4
-rw-r--r--src/protocol_ssh.c36
-rw-r--r--src/utils.c60
8 files changed, 228 insertions, 51 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 1ac657b..c2fe07c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,5 +1,5 @@
sbin_PROGRAMS = potd
-potd_SOURCES = utils.c options.c log.c log_colored.c log_file.c socket.c pevent.c capabilities.c filesystem.c jail.c forward.c redirector.c protocol.c protocol_ssh.c main.c
+potd_SOURCES = compat.c utils.c options.c log.c log_colored.c log_file.c socket.c pevent.c capabilities.c filesystem.c jail.c forward.c redirector.c protocol.c protocol_ssh.c main.c
if HAVE_SECCOMP
potd_SOURCES += pseccomp.c
endif
diff --git a/src/compat.c b/src/compat.c
new file mode 100644
index 0000000..72c78a3
--- /dev/null
+++ b/src/compat.c
@@ -0,0 +1,104 @@
+/*
+ * compat.c
+ * potd is licensed under the BSD license:
+ *
+ * Copyright (c) 2018 Toni Uhlig <matzeton@googlemail.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - 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.
+ *
+ * - The names of its contributors may not be used to endorse or promote
+ * products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <errno.h>
+
+#include "compat.h"
+
+
+char *
+potd_strtok(char *str, const char *delim, char **saveptr)
+{
+#ifdef HAVE_STRTOK_R
+ return strtok_r(str, delim, saveptr);
+#else
+ (void) saveptr;
+
+ return strtok(str, delim);
+#endif
+}
+
+struct tm *
+potd_localtime(const time_t *timep, struct tm *result)
+{
+#ifdef HAVE_LOCALTIME_R
+ return localtime_r(timep, result);
+#else
+ (void) result;
+
+ return localtime(timep);
+#endif
+}
+
+int
+potd_getpwnam(const char *name, struct passwd *pwd)
+{
+ struct passwd *result = NULL;
+
+ errno = 0;
+#ifdef HAVE_GETPWNAM_R
+ char buf[BUFSIZ];
+
+ return getpwnam_r(name, pwd, buf, sizeof buf, &result) || !result;
+#else
+ result = getpwnam(name);
+ if (result)
+ *pwd = *result;
+
+ return result == NULL;
+#endif
+}
+
+int
+potd_getgrnam(const char *name, struct group *grp)
+{
+ struct group *result = NULL;
+
+ errno = 0;
+#ifdef HAVE_GETGRNAM_R
+ char buf[BUFSIZ];
+
+ return getgrnam_r(name, grp, buf, sizeof buf, &result) || !result;
+#else
+ result = getgrnam(name);
+ if (result)
+ *grp = *result;
+
+ return result == NULL;
+#endif
+}
diff --git a/src/compat.h b/src/compat.h
new file mode 100644
index 0000000..386b80e
--- /dev/null
+++ b/src/compat.h
@@ -0,0 +1,55 @@
+/*
+ * compat.h
+ * potd is licensed under the BSD license:
+ *
+ * Copyright (c) 2018 Toni Uhlig <matzeton@googlemail.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - 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.
+ *
+ * - The names of its contributors may not be used to endorse or promote
+ * products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ */
+
+#ifndef POTD_COMPAT_H
+#define POTD_COMPAT_H 1
+
+#include <string.h>
+#include <time.h>
+#include <pwd.h>
+#include <grp.h>
+
+
+char *
+potd_strtok(char *str, const char *delim, char **saveptr);
+
+struct tm *
+potd_localtime(const time_t *timep, struct tm *result);
+
+int
+potd_getpwnam(const char *name, struct passwd *pwd);
+
+int
+potd_getgrnam(const char *name, struct group *grp);
+
+#endif
diff --git a/src/filesystem.c b/src/filesystem.c
index 3284dd4..fa94987 100644
--- a/src/filesystem.c
+++ b/src/filesystem.c
@@ -49,6 +49,7 @@
#include <assert.h>
#include "log.h"
+#include "compat.h"
#include "utils.h"
#include "options.h"
@@ -239,7 +240,7 @@ static MountData *
get_last_mount(void)
{
FILE *fp = fopen("/proc/self/mountinfo", "r");
- char *ptr;
+ char *ptr, *saveptr = NULL;
int cnt = 1;
size_t len;
@@ -265,11 +266,11 @@ get_last_mount(void)
// mdata.dir: /home/netblue/.cache
// mdata.fstype: tmpfs
memset(&mdata, 0, sizeof(mdata));
- ptr = strtok(mbuf, " ");
+ ptr = potd_strtok(mbuf, " ", &saveptr);
if (!ptr)
goto errexit;
- while ((ptr = strtok(NULL, " ")) != NULL) {
+ while ((ptr = potd_strtok(NULL, " ", &saveptr)) != NULL) {
cnt++;
if (cnt == 4) {
mdata.fsname = ptr;
@@ -279,11 +280,11 @@ get_last_mount(void)
}
}
- ptr = strtok(NULL, "-");
+ ptr = potd_strtok(NULL, "-", &saveptr);
if (!ptr)
goto errexit;
- ptr = strtok(NULL, " ");
+ ptr = potd_strtok(NULL, " ", &saveptr);
if (!ptr)
goto errexit;
mdata.fstype = ptr++;
diff --git a/src/log.c b/src/log.c
index 240c12d..20e9444 100644
--- a/src/log.c
+++ b/src/log.c
@@ -35,6 +35,7 @@
#include <time.h>
#include "log.h"
+#include "compat.h"
log_priority log_prio = NOTICE;
log_open_cb log_open = NULL;
@@ -48,12 +49,12 @@ char *
curtime_str(char *buf, size_t siz)
{
time_t t;
- struct tm *tmp;
+ struct tm *tmp, res;
t = time(NULL);
- tmp = localtime(&t);
+ tmp = potd_localtime(&t, &res);
- if (!strftime(buf, siz, "%d %b %y - %H:%M:%S", tmp))
+ if (tmp && !strftime(buf, siz, "%d %b %y - %H:%M:%S", tmp))
snprintf(buf, siz, "%s", "UNKNOWN_TIME");
return buf;
diff --git a/src/main.c b/src/main.c
index 3816a77..9600176 100644
--- a/src/main.c
+++ b/src/main.c
@@ -371,8 +371,8 @@ int main(int argc, char *argv[])
N("%s (C) 2018 Toni Uhlig <%s>", PACKAGE_STRING, PACKAGE_BUGREPORT);
#endif
- ABORT_ON_FATAL( selftest_minimal_requirements(),
- "Selfcheck" );
+ if (selftest_minimal_requirements())
+ exit(EXIT_FAILURE);
if (geteuid() != 0) {
E("%s", "I was made for root!");
diff --git a/src/protocol_ssh.c b/src/protocol_ssh.c
index 9ad5110..7d6e935 100644
--- a/src/protocol_ssh.c
+++ b/src/protocol_ssh.c
@@ -57,6 +57,7 @@
#include "pseccomp.h"
#endif
#include "options.h"
+#include "compat.h"
#include "utils.h"
#include "log.h"
@@ -303,16 +304,16 @@ static int gen_default_keys(void)
char path[PATH_MAX];
char cmd[BUFSIZ];
int s = 0;
- struct passwd *pwd;
+ struct passwd pwd;
errno = 0;
- pwd = getpwnam(getopt_str(OPT_CHUSER));
+ if (potd_getpwnam(getopt_str(OPT_CHUSER), &pwd))
+ return 1;
+
if (mkdir(getopt_str(OPT_SSH_RUN_DIR), R_OK|W_OK|X_OK) && errno == ENOENT) {
if (chmod(getopt_str(OPT_SSH_RUN_DIR), S_IRWXU))
return 1;
- if (!pwd)
- return 1;
- if (chown(getopt_str(OPT_SSH_RUN_DIR), pwd->pw_uid, pwd->pw_gid))
+ if (chown(getopt_str(OPT_SSH_RUN_DIR), pwd.pw_uid, pwd.pw_gid))
return 1;
}
@@ -329,10 +330,8 @@ static int gen_default_keys(void)
}
if (chmod(path, S_IRUSR))
return 1;
- if (pwd) {
- if (chown(path, pwd->pw_uid, pwd->pw_gid))
- return 1;
- }
+ if (chown(path, pwd.pw_uid, pwd.pw_gid))
+ return 1;
snprintf(path, sizeof path, "%s/%s", getopt_str(OPT_SSH_RUN_DIR),
dsa_key_suf);
@@ -347,10 +346,8 @@ static int gen_default_keys(void)
}
if (chmod(path, S_IRUSR))
return 1;
- if (pwd) {
- if (chown(path, pwd->pw_uid, pwd->pw_gid))
- return 1;
- }
+ if (chown(path, pwd.pw_uid, pwd.pw_gid))
+ return 1;
snprintf(path, sizeof path, "%s/%s", getopt_str(OPT_SSH_RUN_DIR),
ecdsa_key_suf);
@@ -365,10 +362,8 @@ static int gen_default_keys(void)
}
if (chmod(path, S_IRUSR))
return 1;
- if (pwd) {
- if (chown(path, pwd->pw_uid, pwd->pw_gid))
- return 1;
- }
+ if (chown(path, pwd.pw_uid, pwd.pw_gid))
+ return 1;
return s != 0;
}
@@ -630,7 +625,7 @@ static int auth_password(const char *user, const char *pass,
size_t i;
double d;
time_t o, t = time(NULL);
- struct tm *tmp;
+ struct tm tmp;
char time_str[64] = {0};
for (i = 0; i < CACHE_MAX; ++i) {
@@ -644,8 +639,9 @@ static int auth_password(const char *user, const char *pass,
strncmp(pass, cache[i].pass, PASS_LEN) == 0 &&
strnlen(pass, PASS_LEN) == strnlen(cache[i].pass, PASS_LEN))
{
- tmp = localtime(&o);
- if (!strftime(time_str, sizeof time_str, "%H:%M:%S", tmp))
+ if (!potd_localtime(&o, &tmp))
+ continue;
+ if (!strftime(time_str, sizeof time_str, "%H:%M:%S", &tmp))
snprintf(time_str, sizeof time_str, "%s", "UNKNOWN_TIME");
N("Got cached user/pass '%s'/'%s' from %s",
user, pass, time_str);
diff --git a/src/utils.c b/src/utils.c
index 3cf88d5..edcfb31 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -63,6 +63,7 @@
#endif
#include "utils.h"
+#include "compat.h"
#ifdef HAVE_SECCOMP
#include "pseccomp.h"
#endif
@@ -379,8 +380,8 @@ int redirect_devnull_to(int fds, ...)
int change_user_group(const char *user, const char *group)
{
- struct passwd *pwd = NULL;
- struct group *grp = NULL;
+ struct passwd pwd;
+ struct group grp;
gid_t gid;
if (group)
@@ -388,22 +389,24 @@ int change_user_group(const char *user, const char *group)
else
D2("Change user to '%s' and its main group", user);
- pwd = getpwnam(user);
- if (!pwd)
+ if (potd_getpwnam(user, &pwd)) {
+ E_STRERR("Get uid from user '%s'", user);
return 1;
+ }
if (!group) {
- gid = pwd->pw_gid;
+ gid = pwd.pw_gid;
} else {
- grp = getgrnam(group);
- if (!grp)
+ if (potd_getgrnam(group, &grp)) {
+ E_STRERR("Get gid from group '%s'", group);
return 1;
- gid = grp->gr_gid;
+ }
+ gid = grp.gr_gid;
}
if (setresgid(gid, gid, gid))
return 1;
- if (setresuid(pwd->pw_uid, pwd->pw_uid, pwd->pw_uid))
+ if (setresuid(pwd.pw_uid, pwd.pw_uid, pwd.pw_uid))
return 1;
return 0;
@@ -1072,6 +1075,8 @@ int selftest_minimal_requirements(void)
goto error;
} else if (s >= 0) {
close(s);
+ if (chmod(getopt_str(OPT_ROFILE), S_IRUSR|S_IWUSR))
+ goto error;
}
if (mkdir(getopt_str(OPT_RODIR), S_IRWXU) && errno != EEXIST) {
E_STRERR("RO-directory '%s' check", getopt_str(OPT_RODIR));
@@ -1091,6 +1096,17 @@ int selftest_minimal_requirements(void)
goto error;
}
+ s = -1;
+ child_pid = fork();
+ if (!child_pid) {
+ if (change_default_user_group())
+ exit(EXIT_FAILURE);
+ else
+ exit(EXIT_SUCCESS);
+ } else waitpid(child_pid, &s, 0);
+ if (s)
+ goto error;
+
/* advanced sandbox tests */
if (getuid() == (uid_t) 0) {
child_pid = fork();
@@ -1103,16 +1119,16 @@ int selftest_minimal_requirements(void)
case 0:
if (clearenv()) {
E_STRERR("%s", "Clearing environment vairables");
- goto error;
+ exit(EXIT_FAILURE);
}
if (cgroups_set() || cgroups_activate()) {
E_STRERR("%s", "Activating cgroups");
- goto error;
+ exit(EXIT_FAILURE);
}
if (unshare(CLONE_NEWUTS|CLONE_NEWPID|CLONE_NEWIPC|CLONE_NEWNS))
{
E_STRERR("%s", "Unshare");
- goto error;
+ exit(EXIT_FAILURE);
}
mount_root();
#ifdef HAVE_SECCOMP
@@ -1120,10 +1136,12 @@ int selftest_minimal_requirements(void)
(getopt_used(OPT_SECCOMP_MINIMAL) ? PS_MINIMUM : 0));
if (pseccomp_default_rules(psc)) {
E_STRERR("%s", "Seccomp");
- goto error;
+ exit(EXIT_FAILURE);
}
pseccomp_free(&psc);
#endif
+
+ s = -1;
child_pid = fork();
if (!child_pid) {
if (safe_chroot(getopt_str(OPT_ROOT)))
@@ -1137,22 +1155,24 @@ int selftest_minimal_requirements(void)
#endif
exit(EXIT_SUCCESS);
} else waitpid(child_pid, &s, 0);
+
exit(s);
- break;
default:
waitpid(child_pid, &s, 0);
+ if (s)
+ goto error;
}
}
- if (getopt_used(OPT_RUNTEST)) {
- N("%s", "Selftest success");
+ N("%s", "Selftest success");
+ if (getopt_used(OPT_RUNTEST))
exit(EXIT_SUCCESS);
- }
+
return 0;
error:
- if (getopt_used(OPT_RUNTEST)) {
- E("%s", "Selftest failed");
+ E("%s", "Selftest failed");
+ if (getopt_used(OPT_RUNTEST))
exit(EXIT_FAILURE);
- }
+
return 1;
}