+ implement UDP, HTTP/HTTPS
* Transport:
- UDP fragmentation
-* UTIL / FS:
- - gnunet-publish tires to connect to service even if
- run with 'simulation' option (-s)
* DHT: [Nate]
- track paths content travels (PUT, reply-to-get) in messages,
pass to client (client API & protocol already support this!)
* FS: [CG]
+ - gnunet-publish tires to connect to service even if
+ run with 'simulation' option (-s)
+ - gnunet-download does not *always* use inline full data (?)
- implement multi-peer FS performance tests
+ insert
+ download
- Remove KBlocks in gnunet-unindex (see discussion with Kenneth Almquist on gnunet-devs in 9/2009)
- use different queue prioritization for probe-downloads vs. normal downloads
- re-implement gnunet-auto-share
-* UTIL: [CG]
- - allow limiting UNIX socket access by UID/GID
* GNUNET-GTK: [CG]
- add tool bar
- do meaningful update to status line (starting up, peer running, #connections, shutdown, ...)
AC_CHECK_HEADERS([fcntl.h math.h errno.h ctype.h limits.h stdio.h stdlib.h string.h unistd.h stdarg.h signal.h locale.h sys/stat.h sys/types.h],,AC_MSG_ERROR([Compiling GNUnet requires standard UNIX headers files]))
# Checks for headers that are only required on some systems or opional (and where we do NOT abort if they are not there)
-AC_CHECK_HEADERS([langinfo.h sys/param.h sys/mount.h sys/statvfs.h sys/select.h sockLib.h sys/mman.h sys/msg.h sys/vfs.h arpa/inet.h fcntl.h libintl.h netdb.h netinet/in.h netinet/in_systm.h sys/ioctl.h sys/socket.h sys/time.h unistd.h kstat.h sys/sysinfo.h kvm.h sys/file.h sys/resource.h ifaddrs.h mach/mach.h stddef.h sys/timeb.h terminos.h argz.h])
+AC_CHECK_HEADERS([langinfo.h sys/param.h sys/mount.h sys/statvfs.h sys/select.h sockLib.h sys/mman.h sys/msg.h sys/vfs.h arpa/inet.h fcntl.h libintl.h netdb.h netinet/in.h netinet/in_systm.h sys/ioctl.h sys/socket.h sys/time.h unistd.h kstat.h sys/sysinfo.h kvm.h sys/file.h sys/resource.h ifaddrs.h mach/mach.h stddef.h sys/timeb.h terminos.h argz.h ucred.h])
SAVE_LDFLAGS=$LDFLAGS
SAVE_CPPFLAGS=$CPPFLAGS
AC_HEADER_SYS_WAIT
AC_TYPE_OFF_T
AC_TYPE_UID_T
-AC_CHECK_FUNCS([floor gethostname memmove rmdir strncasecmp strrchr strtol atoll dup2 fdatasync ftruncate gettimeofday memset mkdir mkfifo select socket strcasecmp strchr strdup strerror strstr clock_gettime getrusage rand uname setlocale getcwd mktime gmtime_r gmtime strlcpy strlcat ftruncate stat64 sbrk mmap mremap setrlimit sysconf gethostbyaddr initgroups getifaddrs freeifaddrs getnameinfo getaddrinfo inet_ntoa localtime_r nl_langinfo putenv realpath strndup gethostbyname2 gethostbyname])
+AC_CHECK_FUNCS([floor gethostname memmove rmdir strncasecmp strrchr strtol atoll dup2 fdatasync ftruncate gettimeofday memset mkdir mkfifo select socket strcasecmp strchr strdup strerror strstr clock_gettime getrusage rand uname setlocale getcwd mktime gmtime_r gmtime strlcpy strlcat ftruncate stat64 sbrk mmap mremap setrlimit sysconf gethostbyaddr initgroups getifaddrs freeifaddrs getnameinfo getaddrinfo inet_ntoa localtime_r nl_langinfo putenv realpath strndup gethostbyname2 gethostbyname getpeerucred getpeereid])
# restore LIBS
LIBS=$SAVE_LIBS
ACCEPT_FROM6 = ::1;
DEFAULTSERVICES = topology hostlist
UNIXPATH = /tmp/gnunet-service-arm.sock
+UNIX_MATCH_UID = YES
+UNIX_MATCH_GID = YES
# GLOBAL_POSTFIX = -l $SERVICEHOME/{}-logs
# GLOBAL_PREFIX =
# USERNAME =
ACCEPT_FROM = 127.0.0.1;
ACCEPT_FROM6 = ::1;
UNIXPATH = /tmp/gnunet-service-statistics.sock
+UNIX_MATCH_UID = NO
+UNIX_MATCH_GID = YES
# DISABLE_SOCKET_FORWARDING = NO
# USERNAME =
# MAXBUF =
ACCEPT_FROM = 127.0.0.1;
ACCEPT_FROM6 = ::1;
UNIXPATH = /tmp/gnunet-service-resolver.sock
+UNIX_MATCH_UID = NO
+UNIX_MATCH_GID = NO
# DISABLE_SOCKET_FORWARDING = NO
# USERNAME =
# MAXBUF =
ACCEPT_FROM = 127.0.0.1;
ACCEPT_FROM6 = ::1;
UNIXPATH = /tmp/gnunet-service-peerinfo.sock
+UNIX_MATCH_UID = NO
+UNIX_MATCH_GID = YES
# DISABLE_SOCKET_FORWARDING = NO
# USERNAME =
# MAXBUF =
PLUGINS = tcp
UNIXPATH = /tmp/gnunet-service-transport.sock
BLACKLIST_FILE = $SERVICEHOME/blacklist
+UNIX_MATCH_UID = YES
+UNIX_MATCH_GID = YES
# DISABLE_SOCKET_FORWARDING = NO
# USERNAME =
# MAXBUF =
TOTAL_QUOTA_IN = 65536
TOTAL_QUOTA_OUT = 65536
UNIXPATH = /tmp/gnunet-service-core.sock
+UNIX_MATCH_UID = YES
+UNIX_MATCH_GID = YES
# DISABLE_SOCKET_FORWARDING = NO
# DEBUG = YES
# USERNAME =
[datastore]
AUTOSTART = YES
UNIXPATH = /tmp/gnunet-service-datastore.sock
+UNIX_MATCH_UID = YES
+UNIX_MATCH_GID = YES
PORT = 2093
HOSTNAME = localhost
HOME = $SERVICEHOME
CONTENT_PUSHING = YES
UNIXPATH = /tmp/gnunet-service-fs.sock
+UNIX_MATCH_UID = NO
+UNIX_MATCH_GID = YES
# DISABLE_SOCKET_FORWARDING = NO
# DEBUG = YES
MAX_PENDING_REQUESTS = 65536
ACCEPT_FROM6 = ::1;
BUCKET_SIZE = 4
UNIXPATH = /tmp/gnunet-service-dht.sock
+UNIX_MATCH_UID = YES
+UNIX_MATCH_GID = YES
# DISABLE_SOCKET_FORWARDING = NO
# DEBUG = YES
# USERNAME =
struct GNUNET_CONNECTION_Handle;
+/**
+ * Credentials for UNIX domain sockets.
+ */
+struct GNUNET_CONNECTION_Credentials
+{
+ /**
+ * UID of the other end of the connection.
+ */
+ uid_t uid;
+
+ /**
+ * GID of the other end of the connection.
+ */
+ gid_t gid;
+};
+
+
/**
* Function to call for access control checks.
*
* @param cls closure
+ * @param ucred credentials, if available, otherwise NULL
* @param addr address
* @param addrlen length of address
* @return GNUNET_YES to allow, GNUNET_NO to deny, GNUNET_SYSERR
* for unknown address family (will be denied).
*/
typedef int (*GNUNET_CONNECTION_AccessCheck) (void *cls,
+ const struct GNUNET_CONNECTION_Credentials *ucred,
const struct sockaddr * addr,
socklen_t addrlen);
void GNUNET_NETWORK_fdset_copy (struct GNUNET_NETWORK_FDSet *to,
const struct GNUNET_NETWORK_FDSet *from);
+
/**
* Return file descriptor for this network handle
*
#include <sys/loadavg.h>
#include <semaphore.h>
#endif
+#if HAVE_UCRED_H
+#include <ucred.h>
+#endif
#ifdef CYGWIN
#include <windows.h>
#include <cygwin/if.h>
struct sockaddr_in6 *v6;
struct sockaddr *sa;
void *uaddr;
+ struct GNUNET_CONNECTION_Credentials *gcp;
+ struct GNUNET_CONNECTION_Credentials gc;
+#ifdef SO_PEERCRED
+ struct ucred uc;
+ socklen_t olen;
+#endif
addrlen = sizeof (addr);
sock =
uaddr = GNUNET_malloc (addrlen);
memcpy (uaddr, addr, addrlen);
}
+ gcp = NULL;
+ gc.uid = 0;
+ gc.gid = 0;
+ if (sa->sa_family == AF_UNIX)
+ {
+#if HAVE_GETPEEREID
+ /* most BSDs */
+ if (0 == getpeereid (GNUNET_NETWORK_get_fd (sock),
+ &gc.uid,
+ &gc.gid))
+ gcp = &gc;
+#else
+#ifdef SO_PEERCRED
+ /* largely traditional GNU/Linux */
+ olen = sizeof (uc);
+ if ( (0 ==
+ getsockopt (GNUNET_NETWORK_get_fd (sock),
+ SOL_SOCKET, SO_PEERCRED, &uc, &olen)) &&
+ (olen == sizeof (uc)) )
+ {
+ gc.uid = uc.uid;
+ gc.gid = uc.gid;
+ gcp = &gc;
+ }
+#else
+#if HAVE_GETPEERUCRED
+ /* this is for Solaris 10 */
+ ucred_t *uc;
+
+ uc = NULL;
+ if (0 == getpeerucred (GNUNET_NETWORK_get_fd (sock), &uc))
+ {
+ gc.uid = ucred_geteuid (uc);
+ gc.gid = ucred_getegid (uc);
+ gcp = &gc;
+ }
+ ucred_free (uc);
+#endif
+#endif
+#endif
+ }
if ((access != NULL) &&
- (GNUNET_YES != (aret = access (access_cls, uaddr, addrlen))))
+ (GNUNET_YES != (aret = access (access_cls, gcp, uaddr, addrlen))))
{
if (aret == GNUNET_NO)
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
return GNUNET_NO;
}
+
/**
* Read data from a connected socket (always non-blocking).
* @param desc socket
#endif
}
+
+/**
+ * Return file descriptor for this network handle
+ *
+ * @param desc wrapper to process
+ * @return POSIX file descriptor
+ */
int
GNUNET_NETWORK_get_fd (struct GNUNET_NETWORK_Handle *desc)
{
return desc->fd;
}
+
/**
* Copy a native fd set
*
*/
int require_found;
+ /**
+ * Do we require a matching UID for UNIX domain socket
+ * connections?
+ */
+ int match_uid;
+
+ /**
+ * Do we require a matching GID for UNIX domain socket
+ * connections?
+ */
+ int match_gid;
+
/**
* Our options.
*/
/**
* Check if access to the service is allowed from the given address.
+ *
+ * @param cls closure
+ * @param uc credentials, if available, otherwise NULL
+ * @param addr address
+ * @param addrlen length of address
+ * @return GNUNET_YES to allow, GNUNET_NO to deny, GNUNET_SYSERR
+ * for unknown address family (will be denied).
*/
static int
-check_access (void *cls, const struct sockaddr *addr, socklen_t addrlen)
+check_access (void *cls,
+ const struct GNUNET_CONNECTION_Credentials *uc,
+ const struct sockaddr *addr, socklen_t addrlen)
{
struct GNUNET_SERVICE_Context *sctx = cls;
const struct sockaddr_in *i4;
(!check_ipv6_listed (sctx->v6_denied, &i6->sin6_addr)));
break;
case AF_UNIX:
- /* FIXME: support checking UID/GID in the future... */
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
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ _("Access denied to UID %d / GID %d\n"),
+ (uc == NULL) ? -1 : uc->uid,
+ (uc == NULL) ? -1 : uc->gid);
break;
default:
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
&sctx->addrlens)) )
return GNUNET_SYSERR;
sctx->require_found = tolerant ? GNUNET_NO : GNUNET_YES;
-
+ sctx->match_uid = GNUNET_CONFIGURATION_get_value_yesno (sctx->cfg,
+ sctx->serviceName,
+ "UNIX_MATCH_UID");
+ sctx->match_gid = GNUNET_CONFIGURATION_get_value_yesno (sctx->cfg,
+ sctx->serviceName,
+ "UNIX_MATCH_GID");
process_acl4 (&sctx->v4_denied, sctx, "REJECT_FROM");
process_acl4 (&sctx->v4_allowed, sctx, "ACCEPT_FROM");
process_acl6 (&sctx->v6_denied, sctx, "REJECT_FROM6");