From fb1390dfeb7e98a404207988f13341522f3692b6 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Fri, 13 Jan 2012 22:10:16 +0000 Subject: improving code and build system to be in line with gnunet access control model for services as described at https://gnunet.org/gnunet-access-control-model --- src/dht/dht.conf.in | 1 + src/dns/Makefile.am | 7 +++-- src/dns/dns.conf.in | 5 ++-- src/dv/dv.conf.in | 2 ++ src/transport/transport.conf.in | 1 + src/util/service.c | 65 ++++++++++++++++++++++++++++++++--------- src/vpn/vpn.conf.in | 2 ++ 7 files changed, 65 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/dht/dht.conf.in b/src/dht/dht.conf.in index c73c05688..17c13e93e 100644 --- a/src/dht/dht.conf.in +++ b/src/dht/dht.conf.in @@ -9,6 +9,7 @@ ACCEPT_FROM = 127.0.0.1; ACCEPT_FROM6 = ::1; BUCKET_SIZE = 4 UNIXPATH = /tmp/gnunet-service-dht.sock +# This could be relaxed... UNIX_MATCH_UID = YES UNIX_MATCH_GID = YES # DISABLE_SOCKET_FORWARDING = NO diff --git a/src/dns/Makefile.am b/src/dns/Makefile.am index f7376a111..99e78d7d6 100644 --- a/src/dns/Makefile.am +++ b/src/dns/Makefile.am @@ -20,8 +20,11 @@ HIJACKBIN = gnunet-helper-hijack-dns gnunet-helper-dns install-exec-hook: $(SUDO_BINARY) chown root:root $(bindir)/gnunet-helper-hijack-dns || true $(SUDO_BINARY) chmod u+s $(bindir)/gnunet-helper-hijack-dns || true - $(SUDO_BINARY) chown root:root $(bindir)/gnunet-helper-dns || true - $(SUDO_BINARY) chmod u+s $(bindir)/gnunet-helper-dns || true + $(SUDO_BINARY) chown root $(bindir)/gnunet-helper-dns || true + $(SUDO_BINARY) chgrp $(GNUNETDNS_GROUP) $(bindir)/gnunet-helper-dns || true + $(SUDO_BINARY) chmod 4750 $(bindir)/gnunet-helper-dns || true + $(SUDO_BINARY) chgrp $(GNUNETDNS_GROUP) $(bindir)/gnunet-service-dns-new || true + $(SUDO_BINARY) chmod 2755 $(bindir)/gnunet-helper-dns || true else install-exec-hook: endif diff --git a/src/dns/dns.conf.in b/src/dns/dns.conf.in index cd1c2e6e3..a99f7fec3 100644 --- a/src/dns/dns.conf.in +++ b/src/dns/dns.conf.in @@ -5,10 +5,9 @@ HOSTNAME = localhost HOME = $SERVICEHOME CONFIG = $DEFAULTCONFIG BINARY = gnunet-service-dns -ACCEPT_FROM = 127.0.0.1; -ACCEPT_FROM6 = ::1; UNIXPATH = /tmp/gnunet-service-dns.sock - +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES PROVIDE_EXIT = YES IFNAME = gnunet-dns diff --git a/src/dv/dv.conf.in b/src/dv/dv.conf.in index fa647e31c..93278df7c 100644 --- a/src/dv/dv.conf.in +++ b/src/dv/dv.conf.in @@ -9,6 +9,8 @@ HOME = $SERVICEHOME HOSTNAME = localhost @UNIXONLY@ PORT = 2571 UNIXPATH = /tmp/gnunet-service-dv.sock +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES # ACCEPT_FROM = # ACCEPT_FROM6 = # REJECT_FROM = diff --git a/src/transport/transport.conf.in b/src/transport/transport.conf.in index 213e8f5f0..ff81ff088 100644 --- a/src/transport/transport.conf.in +++ b/src/transport/transport.conf.in @@ -12,6 +12,7 @@ ACCEPT_FROM6 = ::1; PLUGINS = tcp UNIXPATH = /tmp/gnunet-service-transport.sock BLACKLIST_FILE = $SERVICEHOME/blacklist +# This could possibly be relaxed UNIX_MATCH_UID = YES UNIX_MATCH_GID = YES # DISABLE_SOCKET_FORWARDING = NO diff --git a/src/util/service.c b/src/util/service.c index 8235830c9..243e7daa9 100644 --- a/src/util/service.c +++ b/src/util/service.c @@ -501,14 +501,18 @@ struct GNUNET_SERVICE_Context int require_found; /** - * Do we require a matching UID for UNIX domain socket - * connections? + * Do we require a matching UID for UNIX domain socket connections? + * GNUNET_NO means that the UID does not have to match (however, + * "match_gid" may still impose other access control checks). */ int match_uid; /** - * Do we require a matching GID for UNIX domain socket - * connections? + * Do we require a matching GID for UNIX domain socket connections? + * Ignored if "match_uid" is GNUNET_YES. Note that this is about + * checking that the client's UID is in our group OR that the + * client's GID is our GID. If both "match_gid" and "match_uid" are + * "GNUNET_NO", all users on the local system have access. */ int match_gid; @@ -617,15 +621,50 @@ check_access (void *cls, const struct GNUNET_CONNECTION_Credentials *uc, #ifndef WINDOWS case AF_UNIX: ret = GNUNET_OK; /* always OK for now */ - if ((sctx->match_uid == GNUNET_YES) || (sctx->match_gid == GNUNET_YES)) - ret = GNUNET_NO; - if ((uc != NULL) && - ((sctx->match_uid != GNUNET_YES) || (uc->uid == geteuid ()) || - (uc->uid == getuid ())) && ((sctx->match_gid != GNUNET_YES) || - (uc->gid == getegid ()) || - (uc->gid == getgid ()))) - ret = GNUNET_YES; - else + if (sctx->match_uid == GNUNET_YES) + { + /* UID match required */ + ret = (uc != NULL) && (uc->uid == geteuid ()); + } + else if (sctx->match_gid == GNUNET_YES) + { + /* group match required */ + if (uc == NULL) + { + /* no credentials, group match not possible */ + ret = GNUNET_NO; + } + else + { + struct group *grp; + unsigned int i; + + if (uc->gid != getegid()) + { + /* default group did not match, but maybe the user is in our group, let's check */ + grp = getgrgid (getegid ()); + if (NULL == grp) + { + GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "getgrgid"); + return GNUNET_NO; + } + ret = GNUNET_NO; + for (i=0; NULL != grp->gr_mem[i]; i++) + { + struct passwd *nam = getpwnam (grp->gr_mem[i]); + if (NULL == nam) + continue; /* name in group that is not in user DB !? */ + if (nam->pw_uid == uc->uid) + { + /* yes, uid is in our group, allow! */ + ret = GNUNET_YES; + break; + } + } + } + } + } + if (GNUNET_NO == ret) LOG (GNUNET_ERROR_TYPE_WARNING, _("Access denied to UID %d / GID %d\n"), (uc == NULL) ? -1 : uc->uid, (uc == NULL) ? -1 : uc->gid); break; diff --git a/src/vpn/vpn.conf.in b/src/vpn/vpn.conf.in index 411ad3fb9..f5eb22447 100644 --- a/src/vpn/vpn.conf.in +++ b/src/vpn/vpn.conf.in @@ -8,6 +8,8 @@ BINARY = gnunet-service-vpn ACCEPT_FROM = 127.0.0.1; ACCEPT_FROM6 = ::1; UNIXPATH = /tmp/gnunet-service-vpn.sock +UNIX_MATCH_UID = YES +UNIX_MATCH_GID = YES IPV6ADDR = 1234::1 IPV6PREFIX = 32 -- cgit v1.2.3