aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/transport/plugin_transport_unix.c22
-rw-r--r--src/util/client.c17
-rw-r--r--src/util/connection.c10
-rw-r--r--src/util/network.c29
-rw-r--r--src/util/service.c37
-rw-r--r--src/util/util.conf5
6 files changed, 97 insertions, 23 deletions
diff --git a/src/transport/plugin_transport_unix.c b/src/transport/plugin_transport_unix.c
index 56e1de426..6c0a02e2c 100644
--- a/src/transport/plugin_transport_unix.c
+++ b/src/transport/plugin_transport_unix.c
@@ -384,7 +384,8 @@ unix_address_to_string (void *cls, const void *addr, size_t addrlen)
384 384
385 385
386static struct sockaddr_un * 386static struct sockaddr_un *
387unix_address_to_sockaddr (const char *unixpath, 387unix_address_to_sockaddr (const struct GNUNET_CONFIGURATION_Handle *cfg,
388 const char *unixpath,
388 socklen_t *sock_len) 389 socklen_t *sock_len)
389{ 390{
390 struct sockaddr_un *un; 391 struct sockaddr_un *un;
@@ -398,6 +399,17 @@ unix_address_to_sockaddr (const char *unixpath,
398 slen = sizeof (un->sun_path) - 1; 399 slen = sizeof (un->sun_path) - 1;
399 memcpy (un->sun_path, unixpath, slen); 400 memcpy (un->sun_path, unixpath, slen);
400 un->sun_path[slen] = '\0'; 401 un->sun_path[slen] = '\0';
402#ifdef LINUX
403 {
404 int abstract;
405
406 abstract = GNUNET_CONFIGURATION_get_value_yesno (cfg,
407 "TESTING",
408 "USE_ABSTRACT_SOCKETS");
409 if (GNUNET_YES == abstract)
410 un->sun_path[0] = '\0';
411 }
412#endif
401 slen = sizeof (struct sockaddr_un); 413 slen = sizeof (struct sockaddr_un);
402#if HAVE_SOCKADDR_IN_SIN_LEN 414#if HAVE_SOCKADDR_IN_SIN_LEN
403 un->sun_len = (u_char) slen; 415 un->sun_len = (u_char) slen;
@@ -633,7 +645,9 @@ unix_real_send (void *cls,
633 645
634 /* Prepare address */ 646 /* Prepare address */
635 unixpath = (const char *) &addr[1]; 647 unixpath = (const char *) &addr[1];
636 if (NULL == (un = unix_address_to_sockaddr (unixpath, &un_len))) 648 if (NULL == (un = unix_address_to_sockaddr (plugin->env->cfg,
649 unixpath,
650 &un_len)))
637 { 651 {
638 GNUNET_break (0); 652 GNUNET_break (0);
639 return -1; 653 return -1;
@@ -1252,7 +1266,9 @@ unix_transport_server_start (void *cls)
1252 struct sockaddr_un *un; 1266 struct sockaddr_un *un;
1253 socklen_t un_len; 1267 socklen_t un_len;
1254 1268
1255 un = unix_address_to_sockaddr (plugin->unix_socket_path, &un_len); 1269 un = unix_address_to_sockaddr (plugin->env->cfg,
1270 plugin->unix_socket_path,
1271 &un_len);
1256 plugin->ats_network = plugin->env->get_address_type (plugin->env->cls, (const struct sockaddr *) un, un_len); 1272 plugin->ats_network = plugin->env->get_address_type (plugin->env->cls, (const struct sockaddr *) un, un_len);
1257 plugin->unix_sock.desc = 1273 plugin->unix_sock.desc =
1258 GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_DGRAM, 0); 1274 GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_DGRAM, 0);
diff --git a/src/util/client.c b/src/util/client.c
index ea3cc45f4..02bec5a8f 100644
--- a/src/util/client.c
+++ b/src/util/client.c
@@ -842,6 +842,7 @@ GNUNET_CLIENT_service_test (const char *service,
842 /* probe UNIX support */ 842 /* probe UNIX support */
843 struct sockaddr_un s_un; 843 struct sockaddr_un s_un;
844 char *unixpath; 844 char *unixpath;
845 int abstract;
845 846
846 unixpath = NULL; 847 unixpath = NULL;
847 if ((GNUNET_OK == 848 if ((GNUNET_OK ==
@@ -862,17 +863,29 @@ GNUNET_CLIENT_service_test (const char *service,
862 _("Using `%s' instead\n"), unixpath); 863 _("Using `%s' instead\n"), unixpath);
863 } 864 }
864 } 865 }
865 if (NULL != unixpath) 866#ifdef LINUX
867 abstract = GNUNET_CONFIGURATION_get_value_yesno (cfg,
868 "TESTING",
869 "USE_ABSTRACT_SOCKETS");
870#else
871 abstract = GNUNET_NO;
872#endif
873 if ((NULL != unixpath) && (GNUNET_YES != abstract))
866 { 874 {
867 if (GNUNET_SYSERR == GNUNET_DISK_directory_create_for_file (unixpath)) 875 if (GNUNET_SYSERR == GNUNET_DISK_directory_create_for_file (unixpath))
868 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, 876 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
869 "mkdir", unixpath); 877 "mkdir", unixpath);
878 }
879 if (NULL != unixpath)
880 {
870 sock = GNUNET_NETWORK_socket_create (PF_UNIX, SOCK_STREAM, 0); 881 sock = GNUNET_NETWORK_socket_create (PF_UNIX, SOCK_STREAM, 0);
871 if (NULL != sock) 882 if (NULL != sock)
872 { 883 {
873 memset (&s_un, 0, sizeof (s_un)); 884 memset (&s_un, 0, sizeof (s_un));
874 s_un.sun_family = AF_UNIX; 885 s_un.sun_family = AF_UNIX;
875 strncpy (s_un.sun_path, unixpath, sizeof (s_un.sun_path) - 1); 886 strncpy (s_un.sun_path, unixpath, sizeof (s_un.sun_path) - 1);
887 if (GNUNET_YES == abstract)
888 s_un.sun_path[0] = '\0';
876#if HAVE_SOCKADDR_IN_SIN_LEN 889#if HAVE_SOCKADDR_IN_SIN_LEN
877 s_un.sun_len = (u_char) sizeof (struct sockaddr_un); 890 s_un.sun_len = (u_char) sizeof (struct sockaddr_un);
878#endif 891#endif
diff --git a/src/util/connection.c b/src/util/connection.c
index 39dad12c3..fb20617fd 100644
--- a/src/util/connection.c
+++ b/src/util/connection.c
@@ -832,6 +832,16 @@ GNUNET_CONNECTION_create_from_connect_to_unixpath (const struct
832 un = GNUNET_new (struct sockaddr_un); 832 un = GNUNET_new (struct sockaddr_un);
833 un->sun_family = AF_UNIX; 833 un->sun_family = AF_UNIX;
834 strncpy (un->sun_path, unixpath, sizeof (un->sun_path) - 1); 834 strncpy (un->sun_path, unixpath, sizeof (un->sun_path) - 1);
835#ifdef LINUX
836 {
837 int abstract;
838
839 abstract = GNUNET_CONFIGURATION_get_value_yesno (cfg, "TESTING",
840 "USE_ABSTRACT_SOCKETS");
841 if (GNUNET_YES == abstract)
842 un->sun_path[0] = '\0';
843 }
844#endif
835#if HAVE_SOCKADDR_IN_SIN_LEN 845#if HAVE_SOCKADDR_IN_SIN_LEN
836 un->sun_len = (u_char) sizeof (struct sockaddr_un); 846 un->sun_len = (u_char) sizeof (struct sockaddr_un);
837#endif 847#endif
diff --git a/src/util/network.c b/src/util/network.c
index 2ee1a73a0..d321a7009 100644
--- a/src/util/network.c
+++ b/src/util/network.c
@@ -420,17 +420,23 @@ GNUNET_NETWORK_socket_bind (struct GNUNET_NETWORK_Handle *desc,
420#endif 420#endif
421#ifndef WINDOWS 421#ifndef WINDOWS
422 { 422 {
423 /* set permissions of newly created UNIX domain socket to "user-only"; applications 423 /* set permissions of newly created non-abstract UNIX domain socket to
424 can choose to relax this later */ 424 "user-only"; applications can choose to relax this later */
425 mode_t old_mask = 0; /* assigned to make compiler happy */ 425 mode_t old_mask = 0; /* assigned to make compiler happy */
426 426 const struct sockaddr_un *un;
427 if (AF_UNIX == address->sa_family) 427 int not_abstract = 0;
428
429 if ((AF_UNIX == address->sa_family)
430 && (NULL != (un = (const struct sockaddr_un *) address)->sun_path)
431 && ('\0' != un->sun_path[0]) ) /* Not an abstract socket */
432 not_abstract = 1;
433 if (not_abstract)
428 old_mask = umask (S_IWGRP | S_IRGRP | S_IXGRP | S_IWOTH | S_IROTH | S_IXOTH); 434 old_mask = umask (S_IWGRP | S_IRGRP | S_IXGRP | S_IWOTH | S_IROTH | S_IXOTH);
429#endif 435#endif
430 436
431 ret = bind (desc->fd, address, address_len); 437 ret = bind (desc->fd, address, address_len);
432#ifndef WINDOWS 438#ifndef WINDOWS
433 if (AF_UNIX == address->sa_family) 439 if (not_abstract)
434 (void) umask (old_mask); 440 (void) umask (old_mask);
435 } 441 }
436#endif 442#endif
@@ -460,7 +466,7 @@ GNUNET_NETWORK_socket_close (struct GNUNET_NETWORK_Handle *desc)
460{ 466{
461 int ret; 467 int ret;
462 468
463#ifdef MINGW 469#ifdef WINDOWS
464 DWORD error = 0; 470 DWORD error = 0;
465 471
466 SetLastError (0); 472 SetLastError (0);
@@ -473,10 +479,15 @@ GNUNET_NETWORK_socket_close (struct GNUNET_NETWORK_Handle *desc)
473#else 479#else
474 ret = close (desc->fd); 480 ret = close (desc->fd);
475#endif 481#endif
476#ifndef MINGW 482#ifndef WINDOWS
477 if ((desc->af == AF_UNIX) && (NULL != desc->addr)) 483 const struct sockaddr_un *un;
484
485 /* Cleanup the UNIX domain socket and its parent directories in case of non
486 abstract sockets */
487 if ((AF_UNIX == desc->af) && (NULL != desc->addr)
488 && (NULL != (un = (const struct sockaddr_un *) desc->addr)->sun_path)
489 && ('\0' != un->sun_path[0]))
478 { 490 {
479 const struct sockaddr_un *un = (const struct sockaddr_un *) desc->addr;
480 char *dirname = GNUNET_strndup (un->sun_path, 491 char *dirname = GNUNET_strndup (un->sun_path,
481 sizeof (un->sun_path)); 492 sizeof (un->sun_path));
482 493
diff --git a/src/util/service.c b/src/util/service.c
index c03247a6d..deb0be46b 100644
--- a/src/util/service.c
+++ b/src/util/service.c
@@ -475,10 +475,13 @@ process_acl6 (struct GNUNET_STRINGS_IPv6NetworkPolicy **ret, struct GNUNET_SERVI
475 * @param saddrs array to update 475 * @param saddrs array to update
476 * @param saddrlens where to store the address length 476 * @param saddrlens where to store the address length
477 * @param unixpath path to add 477 * @param unixpath path to add
478 * @param abstract GNUNET_YES to add an abstract UNIX domain socket. This
479 * parameter is ignore on systems other than LINUX
478 */ 480 */
479static void 481static void
480add_unixpath (struct sockaddr **saddrs, socklen_t * saddrlens, 482add_unixpath (struct sockaddr **saddrs, socklen_t * saddrlens,
481 const char *unixpath) 483 const char *unixpath,
484 int abstract)
482{ 485{
483#ifdef AF_UNIX 486#ifdef AF_UNIX
484 struct sockaddr_un *un; 487 struct sockaddr_un *un;
@@ -486,6 +489,10 @@ add_unixpath (struct sockaddr **saddrs, socklen_t * saddrlens,
486 un = GNUNET_new (struct sockaddr_un); 489 un = GNUNET_new (struct sockaddr_un);
487 un->sun_family = AF_UNIX; 490 un->sun_family = AF_UNIX;
488 strncpy (un->sun_path, unixpath, sizeof (un->sun_path) - 1); 491 strncpy (un->sun_path, unixpath, sizeof (un->sun_path) - 1);
492#ifdef LINUX
493 if (GNUNET_YES == abstract)
494 un->sun_path[0] = '\0';
495#endif
489#if HAVE_SOCKADDR_IN_SIN_LEN 496#if HAVE_SOCKADDR_IN_SIN_LEN
490 un->sun_len = (u_char) sizeof (struct sockaddr_un); 497 un->sun_len = (u_char) sizeof (struct sockaddr_un);
491#endif 498#endif
@@ -536,6 +543,7 @@ GNUNET_SERVICE_get_server_addresses (const char *service_name,
536 unsigned int i; 543 unsigned int i;
537 int resi; 544 int resi;
538 int ret; 545 int ret;
546 int abstract;
539 struct sockaddr **saddrs; 547 struct sockaddr **saddrs;
540 socklen_t *saddrlens; 548 socklen_t *saddrlens;
541 char *hostname; 549 char *hostname;
@@ -608,6 +616,7 @@ GNUNET_SERVICE_get_server_addresses (const char *service_name,
608 hostname = NULL; 616 hostname = NULL;
609 617
610 unixpath = NULL; 618 unixpath = NULL;
619 abstract = GNUNET_NO;
611#ifdef AF_UNIX 620#ifdef AF_UNIX
612 if ((GNUNET_YES == 621 if ((GNUNET_YES ==
613 GNUNET_CONFIGURATION_have_value (cfg, service_name, "UNIXPATH")) && 622 GNUNET_CONFIGURATION_have_value (cfg, service_name, "UNIXPATH")) &&
@@ -628,8 +637,16 @@ GNUNET_SERVICE_get_server_addresses (const char *service_name,
628 LOG (GNUNET_ERROR_TYPE_INFO, 637 LOG (GNUNET_ERROR_TYPE_INFO,
629 _("Using `%s' instead\n"), unixpath); 638 _("Using `%s' instead\n"), unixpath);
630 } 639 }
631 if (GNUNET_OK != 640#ifdef LINUX
632 GNUNET_DISK_directory_create_for_file (unixpath)) 641 abstract = GNUNET_CONFIGURATION_get_value_yesno (cfg,
642 "TESTING",
643 "USE_ABSTRACT_SOCKETS");
644 if (GNUNET_SYSERR == abstract)
645 abstract = GNUNET_NO;
646#endif
647 if ((GNUNET_YES != abstract)
648 && (GNUNET_OK !=
649 GNUNET_DISK_directory_create_for_file (unixpath)))
633 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, 650 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
634 "mkdir", 651 "mkdir",
635 unixpath); 652 unixpath);
@@ -673,7 +690,7 @@ GNUNET_SERVICE_get_server_addresses (const char *service_name,
673 { 690 {
674 saddrs = GNUNET_malloc (2 * sizeof (struct sockaddr *)); 691 saddrs = GNUNET_malloc (2 * sizeof (struct sockaddr *));
675 saddrlens = GNUNET_malloc (2 * sizeof (socklen_t)); 692 saddrlens = GNUNET_malloc (2 * sizeof (socklen_t));
676 add_unixpath (saddrs, saddrlens, unixpath); 693 add_unixpath (saddrs, saddrlens, unixpath, abstract);
677 GNUNET_free_non_null (unixpath); 694 GNUNET_free_non_null (unixpath);
678 GNUNET_free_non_null (hostname); 695 GNUNET_free_non_null (hostname);
679 *addrs = saddrs; 696 *addrs = saddrs;
@@ -725,7 +742,7 @@ GNUNET_SERVICE_get_server_addresses (const char *service_name,
725 i = 0; 742 i = 0;
726 if (NULL != unixpath) 743 if (NULL != unixpath)
727 { 744 {
728 add_unixpath (saddrs, saddrlens, unixpath); 745 add_unixpath (saddrs, saddrlens, unixpath, abstract);
729 i++; 746 i++;
730 } 747 }
731 next = res; 748 next = res;
@@ -777,7 +794,7 @@ GNUNET_SERVICE_get_server_addresses (const char *service_name,
777 saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t)); 794 saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t));
778 if (NULL != unixpath) 795 if (NULL != unixpath)
779 { 796 {
780 add_unixpath (saddrs, saddrlens, unixpath); 797 add_unixpath (saddrs, saddrlens, unixpath, abstract);
781 i++; 798 i++;
782 } 799 }
783 saddrlens[i] = sizeof (struct sockaddr_in); 800 saddrlens[i] = sizeof (struct sockaddr_in);
@@ -799,7 +816,7 @@ GNUNET_SERVICE_get_server_addresses (const char *service_name,
799 i = 0; 816 i = 0;
800 if (NULL != unixpath) 817 if (NULL != unixpath)
801 { 818 {
802 add_unixpath (saddrs, saddrlens, unixpath); 819 add_unixpath (saddrs, saddrlens, unixpath, abstract);
803 i++; 820 i++;
804 } 821 }
805 saddrlens[i] = sizeof (struct sockaddr_in6); 822 saddrlens[i] = sizeof (struct sockaddr_in6);
@@ -1168,7 +1185,8 @@ service_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1168#ifndef WINDOWS 1185#ifndef WINDOWS
1169 if (NULL != sctx->addrs) 1186 if (NULL != sctx->addrs)
1170 for (i = 0; NULL != sctx->addrs[i]; i++) 1187 for (i = 0; NULL != sctx->addrs[i]; i++)
1171 if (AF_UNIX == sctx->addrs[i]->sa_family) 1188 if ((AF_UNIX == sctx->addrs[i]->sa_family)
1189 && ('\0' != ((const struct sockaddr_un *)sctx->addrs[i])->sun_path[0]))
1172 GNUNET_DISK_fix_permissions (((const struct sockaddr_un *)sctx->addrs[i])->sun_path, 1190 GNUNET_DISK_fix_permissions (((const struct sockaddr_un *)sctx->addrs[i])->sun_path,
1173 sctx->match_uid, 1191 sctx->match_uid,
1174 sctx->match_gid); 1192 sctx->match_gid);
@@ -1589,7 +1607,8 @@ GNUNET_SERVICE_start (const char *service_name,
1589#ifndef WINDOWS 1607#ifndef WINDOWS
1590 if (NULL != sctx->addrs) 1608 if (NULL != sctx->addrs)
1591 for (i = 0; NULL != sctx->addrs[i]; i++) 1609 for (i = 0; NULL != sctx->addrs[i]; i++)
1592 if (AF_UNIX == sctx->addrs[i]->sa_family) 1610 if ((AF_UNIX == sctx->addrs[i]->sa_family)
1611 && ('\0' != ((const struct sockaddr_un *)sctx->addrs[i])->sun_path[0]))
1593 GNUNET_DISK_fix_permissions (((const struct sockaddr_un *)sctx->addrs[i])->sun_path, 1612 GNUNET_DISK_fix_permissions (((const struct sockaddr_un *)sctx->addrs[i])->sun_path,
1594 sctx->match_uid, 1613 sctx->match_uid,
1595 sctx->match_gid); 1614 sctx->match_gid);
diff --git a/src/util/util.conf b/src/util/util.conf
index 3df538f5d..1627b068a 100644
--- a/src/util/util.conf
+++ b/src/util/util.conf
@@ -49,3 +49,8 @@ PRIVATE_KEY = $GNUNET_DATA_HOME/private_key.ecc
49[TESTING] 49[TESTING]
50SPEEDUP_INTERVAL = 0 ms 50SPEEDUP_INTERVAL = 0 ms
51SPEEDUP_DELTA = 0 ms 51SPEEDUP_DELTA = 0 ms
52# This following option is applicable to LINUX. Enabling this option causes all
53# UNIX domain sockets to be opened as abstract sockets. Note that the
54# filesystem level restrictions no longer apply for abstract sockets. An
55# end-user should not modify this option.
56USE_ABSTRACT_SOCKETS = NO