Compare commits

...

9 Commits

Author SHA1 Message Date
Oleksandr Natalenko a6fb980120
Merge ebf4e7ee9e into ec5c89a368 2023-11-29 21:13:44 -07:00
Erik Ekman ec5c89a368
Merge pull request #93 from ffontaine/master
src/osflags: fully fix cross-compilation
2023-11-30 00:29:17 +01:00
Erik Ekman fc174d5e37 Bump github checkout action version
"The following actions uses node12 which is deprecated and will be forced to run on node16: actions/checkout@v2."
2023-11-30 00:26:17 +01:00
Erik Ekman 3b1d3a5d4c
Merge pull request #95 from mmuman/haiku-fixes
Haiku fixes
2023-11-30 00:17:17 +01:00
François Revol 39c3154a77 Haiku has daemon() in libbsd 2023-11-18 18:20:22 +01:00
François Revol 8ba813f08e osflags: on Haiku, require BSD headers and lib 2023-11-18 18:19:14 +01:00
Fabrice Fontaine a5d71d0761 src/osflags: fully fix cross-compilation
Cross-compilation was only partially fixed by
024481c94b
as selinux was still enabled depending on host file existence

Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
2023-11-02 23:03:15 +01:00
Oleksandr Natalenko ebf4e7ee9e check capabilities, not effective user ID
Under Linux, a process may not be run under root, yet it may have a permission
to do what a superuser may do given specific capabilities are granted.

This commit makes iodine not depend on EUID being 0 in order to run
properly. Instead, in presence of libcap-ng, the following capabilities
are being checked:

* `CAP_NET_BIND_SERVICES` for server to bind to a port, lower than
  `/proc/sys/net/ipv4/ip_unprivileged_port_start`
* `CAP_NET_ADMIN` to operate on a TUN device
* `CAP_SETUID` and `CAP_SETGID` in case server is configured to change
  the user it runs on behalf of

This change is handy if iodine is being run under a non-root user, provided
`AmbientCapabilities=` and `CapabilityBoundingSet=` of systemd are employed
in the first place.

Fixes: https://github.com/yarrick/iodine/issues/80
Signed-off-by: Oleksandr Natalenko <oleksandr@redhat.com>
2022-11-02 19:14:09 +01:00
Oleksandr Natalenko 11dd73a646 rename check_superuser() to check_privileges()
It's a preparatory commit to reflect upcoming changes in how
capabilities are checked under Linux in presence of libcap-ng.

No functional change.

Signed-off-by: Oleksandr Natalenko <oleksandr@redhat.com>
2022-10-17 13:53:39 +02:00
10 changed files with 73 additions and 15 deletions

View File

@ -11,7 +11,7 @@ jobs:
runs-on: macos-12
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: make
uses: vmactions/freebsd-vm@v0
with:

View File

@ -12,7 +12,7 @@ jobs:
runs-on: macos-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: make
run: make
- name: install check

View File

@ -11,7 +11,7 @@ jobs:
runs-on: macos-12
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: make
uses: vmactions/openbsd-vm@v0
with:

View File

@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: make
run: make
- name: install check
@ -25,7 +25,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- uses: nttld/setup-ndk@v1
with:
ndk-version: r21e

View File

@ -15,7 +15,7 @@ jobs:
shell: msys2 {0}
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- uses: msys2/setup-msys2@v2
with:
msystem: MINGW64

View File

@ -51,13 +51,18 @@
# include <selinux/selinux.h>
#endif
#ifdef HAVE_LIBCAPNG
#include <stdbool.h>
#include <cap-ng.h>
#endif
#include "common.h"
/* The raw header used when not using DNS protocol */
const unsigned char raw_header[RAW_HDR_LEN] = { 0x10, 0xd1, 0x9e, 0x00 };
/* daemon(3) exists only in 4.4BSD or later, and in GNU libc */
#if !defined(ANDROID) && !defined(WINDOWS32) && !(defined(BSD) && (BSD >= 199306)) && !defined(__GLIBC__)
#if !defined(ANDROID) && !defined(WINDOWS32) && !(defined(BSD) && (BSD >= 199306)) && !defined(__GLIBC__) && !defined(__HAIKU__)
static int daemon(int nochdir, int noclose)
{
int fd, i;
@ -103,12 +108,60 @@ int setgroups(int count, int *groups)
#ifndef WINDOWS32
void
check_superuser(void)
check_privileges(char *username, int port)
{
#if defined HAVE_LIBCAPNG
bool capable = true;
if (capng_get_caps_process() == -1) {
warnx("Unable to get capabilities");
exit(-1);
}
if (!capng_have_capability(CAPNG_EFFECTIVE, CAP_NET_ADMIN)) {
warnx("capabilities: CAP_NET_ADMIN required");
capable = false;
}
if (port) {
unsigned short int ip_unprivileged_port_start = 1024;
FILE *file = fopen("/proc/sys/net/ipv4/ip_unprivileged_port_start", "r");
if (!file) {
warnx("sysctl: unable to get ip_unprivileged_port_start value");
// do not bail out here in case systemd.service has ProcSubset=pid set
} else {
fscanf(file, "%hu", &ip_unprivileged_port_start);
fclose(file);
}
if (port < ip_unprivileged_port_start &&
!capng_have_capability(CAPNG_EFFECTIVE, CAP_NET_BIND_SERVICE)) {
warnx("capabilities: CAP_NET_BIND_SERVICE required");
capable = false;
}
}
if (username) {
if (!capng_have_capability(CAPNG_EFFECTIVE, CAP_SETUID)) {
warnx("capabilities: CAP_SETUID required");
capable = false;
}
if (!capng_have_capability(CAPNG_EFFECTIVE, CAP_SETGID)) {
warnx("capabilities: CAP_SETGID required");
capable = false;
}
}
if (!capable) {
exit(-1);
}
#else
if (geteuid() != 0) {
warnx("Run as root and you'll be happy.");
exit(-1);
}
#endif
}
#endif

View File

@ -105,11 +105,11 @@ enum connection {
};
#ifdef WINDOWS32
static inline void check_superuser(void)
static inline void check_privileges(char *, int)
{
}
#else
void check_superuser(void);
void check_privileges(char *, int);
#endif
char *format_addr(struct sockaddr_storage *sockaddr, int sockaddr_len);
int get_addr(char *, int, int, int, struct sockaddr_storage *);

View File

@ -279,7 +279,7 @@ int main(int argc, char **argv)
}
}
check_superuser();
check_privileges(username, 0);
argc -= optind;
argv += optind;

View File

@ -2519,7 +2519,7 @@ main(int argc, char **argv)
argc -= optind;
argv += optind;
check_superuser();
check_privileges(username, port);
if (argc != 2)
usage();

View File

@ -13,16 +13,17 @@ link)
echo '-lsocket -lbind -lbsd';
;;
Haiku)
echo '-lnetwork';
echo '-lnetwork -lbsd';
;;
windows32)
echo '-lws2_32 -liphlpapi';
;;
Linux)
FLAGS="";
[ -e /usr/include/selinux/selinux.h ] && FLAGS="$FLAGS -lselinux";
"$PKG_CONFIG" --exists libselinux && FLAGS="$FLAGS $($PKG_CONFIG --libs libselinux)";
"$PKG_CONFIG" --exists libsystemd-daemon && FLAGS="$FLAGS $($PKG_CONFIG --libs libsystemd-daemon)";
"$PKG_CONFIG" --exists libsystemd && FLAGS="$FLAGS $($PKG_CONFIG --libs libsystemd)";
"$PKG_CONFIG" --exists libcap-ng && FLAGS="$FLAGS $($PKG_CONFIG --libs libcap-ng)";
echo $FLAGS;
;;
esac
@ -35,14 +36,18 @@ cflags)
BeOS)
echo '-Dsocklen_t=int';
;;
Haiku)
echo '-D_DEFAULT_SOURCE';
;;
Darwin)
echo '-D__APPLE_USE_RFC_3542';
;;
Linux)
FLAGS="-D_GNU_SOURCE"
[ -e /usr/include/selinux/selinux.h ] && FLAGS="$FLAGS -DHAVE_SETCON";
"$PKG_CONFIG" --exists libselinux && FLAGS="$FLAGS -DHAVE_SETCON";
"$PKG_CONFIG" --exists libsystemd-daemon && FLAGS="$FLAGS -DHAVE_SYSTEMD";
"$PKG_CONFIG" --exists libsystemd && FLAGS="$FLAGS -DHAVE_SYSTEMD";
"$PKG_CONFIG" --exists libcap-ng && FLAGS="$FLAGS -DHAVE_LIBCAPNG";
echo $FLAGS;
;;
GNU/kFreeBSD|GNU)