aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2013-10-09 20:03:31 +0000
committerChristian Grothoff <christian@grothoff.org>2013-10-09 20:03:31 +0000
commitbc28ff95e287a6794890c75348075fa9bd7af2f7 (patch)
tree8311c91cfa435c7f0ecef9f27a277edc7ad99b96
parent7e332f5e005af87032decb86ac0a4bfbcc915cdc (diff)
downloadgnunet-bc28ff95e287a6794890c75348075fa9bd7af2f7.tar.gz
gnunet-bc28ff95e287a6794890c75348075fa9bd7af2f7.zip
changing UNIX domain socket access control to file permissions checks, instead of UDS credentials (#2887)
-rw-r--r--src/arm/gnunet-service-arm.c97
-rw-r--r--src/include/gnunet_disk_lib.h17
-rw-r--r--src/util/connection.c3
-rw-r--r--src/util/disk.c29
-rw-r--r--src/util/network.c37
-rw-r--r--src/util/server.c16
-rw-r--r--src/util/service.c138
7 files changed, 192 insertions, 145 deletions
diff --git a/src/arm/gnunet-service-arm.c b/src/arm/gnunet-service-arm.c
index 942534b08..7c759d0ac 100644
--- a/src/arm/gnunet-service-arm.c
+++ b/src/arm/gnunet-service-arm.c
@@ -582,34 +582,36 @@ create_listen_socket (struct sockaddr *sa, socklen_t addr_len,
582 static int on = 1; 582 static int on = 1;
583 struct GNUNET_NETWORK_Handle *sock; 583 struct GNUNET_NETWORK_Handle *sock;
584 struct ServiceListeningInfo *sli; 584 struct ServiceListeningInfo *sli;
585 int match_uid;
586 int match_gid;
585 587
586 switch (sa->sa_family) 588 switch (sa->sa_family)
587 { 589 {
588 case AF_INET: 590 case AF_INET:
589 sock = GNUNET_NETWORK_socket_create (PF_INET, SOCK_STREAM, 0); 591 sock = GNUNET_NETWORK_socket_create (PF_INET, SOCK_STREAM, 0);
590 break; 592 break;
591 case AF_INET6: 593 case AF_INET6:
592 sock = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_STREAM, 0); 594 sock = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_STREAM, 0);
593 break; 595 break;
594 case AF_UNIX: 596 case AF_UNIX:
595 if (strcmp (GNUNET_a2s (sa, addr_len), "@") == 0) /* Do not bind to blank UNIX path! */ 597 if (strcmp (GNUNET_a2s (sa, addr_len), "@") == 0) /* Do not bind to blank UNIX path! */
596 return;
597 sock = GNUNET_NETWORK_socket_create (PF_UNIX, SOCK_STREAM, 0);
598 break;
599 default:
600 GNUNET_break (0);
601 sock = NULL;
602 errno = EAFNOSUPPORT;
603 break;
604 }
605 if (NULL == sock)
606 {
607 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
608 _("Unable to create socket for service `%s': %s\n"),
609 sl->name, STRERROR (errno));
610 GNUNET_free (sa);
611 return; 598 return;
612 } 599 sock = GNUNET_NETWORK_socket_create (PF_UNIX, SOCK_STREAM, 0);
600 break;
601 default:
602 GNUNET_break (0);
603 sock = NULL;
604 errno = EAFNOSUPPORT;
605 break;
606 }
607 if (NULL == sock)
608 {
609 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
610 _("Unable to create socket for service `%s': %s\n"),
611 sl->name, STRERROR (errno));
612 GNUNET_free (sa);
613 return;
614 }
613 if (GNUNET_NETWORK_socket_setsockopt 615 if (GNUNET_NETWORK_socket_setsockopt
614 (sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) != GNUNET_OK) 616 (sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) != GNUNET_OK)
615 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 617 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
@@ -624,22 +626,37 @@ create_listen_socket (struct sockaddr *sa, socklen_t addr_len,
624 626
625 if (GNUNET_OK != 627 if (GNUNET_OK !=
626 GNUNET_NETWORK_socket_bind (sock, (const struct sockaddr *) sa, addr_len)) 628 GNUNET_NETWORK_socket_bind (sock, (const struct sockaddr *) sa, addr_len))
627 { 629 {
628 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 630 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
629 _ 631 _
630 ("Unable to bind listening socket for service `%s' to address `%s': %s\n"), 632 ("Unable to bind listening socket for service `%s' to address `%s': %s\n"),
631 sl->name, GNUNET_a2s (sa, addr_len), STRERROR (errno)); 633 sl->name, GNUNET_a2s (sa, addr_len), STRERROR (errno));
632 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock)); 634 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
633 GNUNET_free (sa); 635 GNUNET_free (sa);
634 return; 636 return;
635 } 637 }
638#ifndef WINDOWS
639 if (AF_UNIX == sa->sa_family)
640 {
641 match_uid =
642 GNUNET_CONFIGURATION_get_value_yesno (cfg, sl->name,
643 "UNIX_MATCH_UID");
644 match_gid =
645 GNUNET_CONFIGURATION_get_value_yesno (cfg, sl->name,
646 "UNIX_MATCH_GID");
647 GNUNET_DISK_fix_permissions (((const struct sockaddr_un *)sa)->sun_path,
648 match_uid,
649 match_gid);
650
651 }
652#endif
636 if (GNUNET_NETWORK_socket_listen (sock, 5) != GNUNET_OK) 653 if (GNUNET_NETWORK_socket_listen (sock, 5) != GNUNET_OK)
637 { 654 {
638 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "listen"); 655 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "listen");
639 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock)); 656 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
640 GNUNET_free (sa); 657 GNUNET_free (sa);
641 return; 658 return;
642 } 659 }
643 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 660 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
644 _("ARM now monitors connections to service `%s' at `%s'\n"), 661 _("ARM now monitors connections to service `%s' at `%s'\n"),
645 sl->name, GNUNET_a2s (sa, addr_len)); 662 sl->name, GNUNET_a2s (sa, addr_len));
diff --git a/src/include/gnunet_disk_lib.h b/src/include/gnunet_disk_lib.h
index f6aa3d070..7de64abff 100644
--- a/src/include/gnunet_disk_lib.h
+++ b/src/include/gnunet_disk_lib.h
@@ -265,7 +265,7 @@ enum GNUNET_DISK_PipeEnd
265 * Checks whether a handle is invalid 265 * Checks whether a handle is invalid
266 * 266 *
267 * @param h handle to check 267 * @param h handle to check
268 * @return GNUNET_YES if invalid, GNUNET_NO if valid 268 * @return #GNUNET_YES if invalid, #GNUNET_NO if valid
269 */ 269 */
270int 270int
271GNUNET_DISK_handle_invalid (const struct GNUNET_DISK_FileHandle *h); 271GNUNET_DISK_handle_invalid (const struct GNUNET_DISK_FileHandle *h);
@@ -506,6 +506,21 @@ GNUNET_DISK_pipe_handle (const struct GNUNET_DISK_PipeHandle *p,
506 */ 506 */
507struct GNUNET_DISK_FileHandle * 507struct GNUNET_DISK_FileHandle *
508GNUNET_DISK_get_handle_from_w32_handle (HANDLE osfh); 508GNUNET_DISK_get_handle_from_w32_handle (HANDLE osfh);
509#else
510
511/**
512 * Update POSIX permissions mask of a file on disk. If both argumets
513 * are #GNUNET_NO, the file is made world-read-write-executable (777).
514 *
515 * @param fn name of the file to update
516 * @param require_uid_match #GNUNET_YES means 700
517 * @param require_gid_match #GNUNET_YES means 770 unless @a require_uid_match is set
518 */
519void
520GNUNET_DISK_fix_permissions (const char *fn,
521 int require_uid_match,
522 int require_gid_match);
523
509#endif 524#endif
510 525
511 526
diff --git a/src/util/connection.c b/src/util/connection.c
index eeabebdf7..5c2ee1b37 100644
--- a/src/util/connection.c
+++ b/src/util/connection.c
@@ -419,7 +419,8 @@ GNUNET_CONNECTION_create_from_accept (GNUNET_CONNECTION_AccessCheck access,
419 (GNUNET_YES != (aret = access (access_cls, gcp, uaddr, addrlen)))) 419 (GNUNET_YES != (aret = access (access_cls, gcp, uaddr, addrlen))))
420 { 420 {
421 if (GNUNET_NO == aret) 421 if (GNUNET_NO == aret)
422 LOG (GNUNET_ERROR_TYPE_INFO, _("Access denied to `%s'\n"), 422 LOG (GNUNET_ERROR_TYPE_INFO,
423 _("Access denied to `%s'\n"),
423 GNUNET_a2s (uaddr, addrlen)); 424 GNUNET_a2s (uaddr, addrlen));
424 GNUNET_break (GNUNET_OK == 425 GNUNET_break (GNUNET_OK ==
425 GNUNET_NETWORK_socket_shutdown (sock, SHUT_RDWR)); 426 GNUNET_NETWORK_socket_shutdown (sock, SHUT_RDWR));
diff --git a/src/util/disk.c b/src/util/disk.c
index 0d24d5a09..03d169780 100644
--- a/src/util/disk.c
+++ b/src/util/disk.c
@@ -463,6 +463,35 @@ mkdtemp (char *fn)
463 strcpy (fn, tfn); 463 strcpy (fn, tfn);
464 return fn; 464 return fn;
465} 465}
466#else
467
468/**
469 * Update POSIX permissions mask of a file on disk. If both argumets
470 * are #GNUNET_NO, the file is made world-read-write-executable (777).
471 *
472 * @param fn name of the file to update
473 * @param require_uid_match #GNUNET_YES means 700
474 * @param require_gid_match #GNUNET_YES means 770 unless @a require_uid_match is set
475 */
476void
477GNUNET_DISK_fix_permissions (const char *fn,
478 int require_uid_match,
479 int require_gid_match)
480{
481 mode_t mode;
482
483 if (GNUNET_YES == require_uid_match)
484 mode = S_IRUSR | S_IWUSR | S_IXUSR;
485 else if (GNUNET_YES == require_gid_match)
486 mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP;
487 else
488 mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH;
489 if (0 != chmod (fn, mode))
490 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
491 "chmod",
492 fn);
493}
494
466#endif 495#endif
467 496
468/** 497/**
diff --git a/src/util/network.c b/src/util/network.c
index 7a4b2a0b3..03dfcddd6 100644
--- a/src/util/network.c
+++ b/src/util/network.c
@@ -87,8 +87,8 @@ GNUNET_NETWORK_test_pf (int pf)
87 { 87 {
88 if (EAFNOSUPPORT == errno) 88 if (EAFNOSUPPORT == errno)
89 return GNUNET_NO; 89 return GNUNET_NO;
90 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 90 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
91 "Failed to create test socket: %s\n", 91 "Failed to create test socket: %s\n",
92 STRERROR (errno)); 92 STRERROR (errno));
93 return GNUNET_SYSERR; 93 return GNUNET_SYSERR;
94 } 94 }
@@ -400,11 +400,14 @@ GNUNET_NETWORK_socket_bind (struct GNUNET_NETWORK_Handle *desc,
400 { 400 {
401 const struct sockaddr_un *address_un = (const struct sockaddr_un *)address; 401 const struct sockaddr_un *address_un = (const struct sockaddr_un *)address;
402 if (address_un->sun_path[0] == '\0') 402 if (address_un->sun_path[0] == '\0')
403 {
403 bind_address_len = \ 404 bind_address_len = \
404 sizeof (struct sockaddr_un) \ 405 sizeof (struct sockaddr_un) \
405 - sizeof (address_un->sun_path) \ 406 - sizeof (address_un->sun_path) \
406 + strnlen (address_un->sun_path + 1, sizeof (address_un->sun_path) - 1) \ 407 + strnlen (address_un->sun_path + 1, sizeof (address_un->sun_path) - 1) \
407 + 1; 408 + 1;
409 GNUNET_break (0);
410 }
408 } 411 }
409#endif 412#endif
410 413
@@ -413,7 +416,7 @@ GNUNET_NETWORK_socket_bind (struct GNUNET_NETWORK_Handle *desc,
413 { 416 {
414 const int on = 1; 417 const int on = 1;
415 418
416 if (desc->af == AF_INET6) 419 if (AF_INET6 == desc->af)
417 if (setsockopt (desc->fd, IPPROTO_IPV6, IPV6_V6ONLY, 420 if (setsockopt (desc->fd, IPPROTO_IPV6, IPV6_V6ONLY,
418 (const void *) &on, 421 (const void *) &on,
419 sizeof (on))) 422 sizeof (on)))
@@ -431,7 +434,22 @@ GNUNET_NETWORK_socket_bind (struct GNUNET_NETWORK_Handle *desc,
431 LOG_STRERROR (GNUNET_ERROR_TYPE_DEBUG, "setsockopt"); 434 LOG_STRERROR (GNUNET_ERROR_TYPE_DEBUG, "setsockopt");
432 } 435 }
433#endif 436#endif
434 ret = bind (desc->fd, address, bind_address_len); 437#ifndef WINDOWS
438 {
439 /* set permissions of newly created UNIX domain socket to "user-only"; applications
440 can choose to relax this later */
441 mode_t old_mask;
442
443 if (AF_UNIX == address->sa_family)
444 old_mask = umask (S_IWGRP | S_IRGRP | S_IXGRP | S_IWOTH | S_IROTH | S_IXOTH);
445#endif
446
447 ret = bind (desc->fd, address, bind_address_len);
448#ifndef WINDOWS
449 if (AF_UNIX == address->sa_family)
450 (void) umask (old_mask);
451 }
452#endif
435#ifdef MINGW 453#ifdef MINGW
436 if (SOCKET_ERROR == ret) 454 if (SOCKET_ERROR == ret)
437 SetErrnoFromWinsockError (WSAGetLastError ()); 455 SetErrnoFromWinsockError (WSAGetLastError ());
@@ -477,8 +495,8 @@ GNUNET_NETWORK_socket_close (struct GNUNET_NETWORK_Handle *desc)
477 const struct sockaddr_un *un = (const struct sockaddr_un *) desc->addr; 495 const struct sockaddr_un *un = (const struct sockaddr_un *) desc->addr;
478 496
479 if (0 != unlink (un->sun_path)) 497 if (0 != unlink (un->sun_path))
480 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, 498 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING,
481 "unlink", 499 "unlink",
482 un->sun_path); 500 un->sun_path);
483 } 501 }
484#endif 502#endif
@@ -550,12 +568,15 @@ GNUNET_NETWORK_socket_connect (const struct GNUNET_NETWORK_Handle *desc,
550 if (address->sa_family == AF_UNIX) 568 if (address->sa_family == AF_UNIX)
551 { 569 {
552 const struct sockaddr_un *address_un = (const struct sockaddr_un *)address; 570 const struct sockaddr_un *address_un = (const struct sockaddr_un *)address;
553 if(address_un->sun_path[0] == '\0') 571 if (address_un->sun_path[0] == '\0')
554 address_len = \ 572 {
573 address_len = \
555 sizeof (struct sockaddr_un) \ 574 sizeof (struct sockaddr_un) \
556 - sizeof (address_un->sun_path) \ 575 - sizeof (address_un->sun_path) \
557 + strnlen (address_un->sun_path + 1, sizeof (address_un->sun_path) - 1) \ 576 + strnlen (address_un->sun_path + 1, sizeof (address_un->sun_path) - 1) \
558 + 1; 577 + 1;
578 GNUNET_break (0);
579 }
559 } 580 }
560#endif 581#endif
561 ret = connect (desc->fd, address, address_len); 582 ret = connect (desc->fd, address, address_len);
diff --git a/src/util/server.c b/src/util/server.c
index 40e7c9f48..8a36877dd 100644
--- a/src/util/server.c
+++ b/src/util/server.c
@@ -392,7 +392,8 @@ GNUNET_SERVER_client_set_user_context_ (struct GNUNET_SERVER_Client *client,
392 * @param tc reason why we are running right now 392 * @param tc reason why we are running right now
393 */ 393 */
394static void 394static void
395process_listen_socket (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 395process_listen_socket (void *cls,
396 const struct GNUNET_SCHEDULER_TaskContext *tc)
396{ 397{
397 struct GNUNET_SERVER_Handle *server = cls; 398 struct GNUNET_SERVER_Handle *server = cls;
398 struct GNUNET_CONNECTION_Handle *sock; 399 struct GNUNET_CONNECTION_Handle *sock;
@@ -417,7 +418,8 @@ process_listen_socket (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
417 server->listen_sockets[i]); 418 server->listen_sockets[i]);
418 if (NULL != sock) 419 if (NULL != sock)
419 { 420 {
420 LOG (GNUNET_ERROR_TYPE_DEBUG, "Server accepted incoming connection.\n"); 421 LOG (GNUNET_ERROR_TYPE_DEBUG,
422 "Server accepted incoming connection.\n");
421 client = GNUNET_SERVER_connect_socket (server, sock); 423 client = GNUNET_SERVER_connect_socket (server, sock);
422 /* decrement reference count, we don't keep "client" alive */ 424 /* decrement reference count, we don't keep "client" alive */
423 GNUNET_SERVER_client_drop (client); 425 GNUNET_SERVER_client_drop (client);
@@ -434,7 +436,7 @@ process_listen_socket (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
434 * Create and initialize a listen socket for the server. 436 * Create and initialize a listen socket for the server.
435 * 437 *
436 * @param server_addr address to listen on 438 * @param server_addr address to listen on
437 * @param socklen length of address 439 * @param socklen length of @a server_addr
438 * @return NULL on error, otherwise the listen socket 440 * @return NULL on error, otherwise the listen socket
439 */ 441 */
440static struct GNUNET_NETWORK_Handle * 442static struct GNUNET_NETWORK_Handle *
@@ -543,7 +545,7 @@ GNUNET_SERVER_create_with_sockets (GNUNET_CONNECTION_AccessCheck access,
543{ 545{
544 struct GNUNET_SERVER_Handle *server; 546 struct GNUNET_SERVER_Handle *server;
545 547
546 server = GNUNET_malloc (sizeof (struct GNUNET_SERVER_Handle)); 548 server = GNUNET_new (struct GNUNET_SERVER_Handle);
547 server->idle_timeout = idle_timeout; 549 server->idle_timeout = idle_timeout;
548 server->listen_sockets = lsocks; 550 server->listen_sockets = lsocks;
549 server->access = access; 551 server->access = access;
@@ -843,7 +845,7 @@ GNUNET_SERVER_add_handlers (struct GNUNET_SERVER_Handle *server,
843{ 845{
844 struct HandlerList *p; 846 struct HandlerList *p;
845 847
846 p = GNUNET_malloc (sizeof (struct HandlerList)); 848 p = GNUNET_new (struct HandlerList);
847 p->handlers = handlers; 849 p->handlers = handlers;
848 p->next = server->handlers; 850 p->next = server->handlers;
849 server->handlers = p; 851 server->handlers = p;
@@ -977,7 +979,7 @@ GNUNET_SERVER_inject (struct GNUNET_SERVER_Handle *server,
977 (GNUNET_SCHEDULER_NO_TASK == sender->warn_task) ) 979 (GNUNET_SCHEDULER_NO_TASK == sender->warn_task) )
978 { 980 {
979 GNUNET_break (0 != type); /* type should never be 0 here, as we don't use 0 */ 981 GNUNET_break (0 != type); /* type should never be 0 here, as we don't use 0 */
980 sender->warn_start = GNUNET_TIME_absolute_get (); 982 sender->warn_start = GNUNET_TIME_absolute_get ();
981 sender->warn_task = 983 sender->warn_task =
982 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, 984 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
983 &warn_no_receive_done, sender); 985 &warn_no_receive_done, sender);
@@ -1235,7 +1237,7 @@ GNUNET_SERVER_connect_socket (struct GNUNET_SERVER_Handle *server,
1235 struct GNUNET_SERVER_Client *client; 1237 struct GNUNET_SERVER_Client *client;
1236 struct NotifyList *n; 1238 struct NotifyList *n;
1237 1239
1238 client = GNUNET_malloc (sizeof (struct GNUNET_SERVER_Client)); 1240 client = GNUNET_new (struct GNUNET_SERVER_Client);
1239 client->connection = connection; 1241 client->connection = connection;
1240 client->reference_count = 1; 1242 client->reference_count = 1;
1241 client->server = server; 1243 client->server = server;
diff --git a/src/util/service.c b/src/util/service.c
index b8975f418..d60cc2885 100644
--- a/src/util/service.c
+++ b/src/util/service.c
@@ -532,17 +532,17 @@ struct GNUNET_SERVICE_Context
532 532
533 /** 533 /**
534 * Do we require a matching UID for UNIX domain socket connections? 534 * Do we require a matching UID for UNIX domain socket connections?
535 * GNUNET_NO means that the UID does not have to match (however, 535 * #GNUNET_NO means that the UID does not have to match (however,
536 * "match_gid" may still impose other access control checks). 536 * @e match_gid may still impose other access control checks).
537 */ 537 */
538 int match_uid; 538 int match_uid;
539 539
540 /** 540 /**
541 * Do we require a matching GID for UNIX domain socket connections? 541 * Do we require a matching GID for UNIX domain socket connections?
542 * Ignored if "match_uid" is GNUNET_YES. Note that this is about 542 * Ignored if @e match_uid is #GNUNET_YES. Note that this is about
543 * checking that the client's UID is in our group OR that the 543 * checking that the client's UID is in our group OR that the
544 * client's GID is our GID. If both "match_gid" and "match_uid" are 544 * client's GID is our GID. If both "match_gid" and @e match_uid are
545 * "GNUNET_NO", all users on the local system have access. 545 * #GNUNET_NO, all users on the local system have access.
546 */ 546 */
547 int match_gid; 547 int match_gid;
548 548
@@ -626,7 +626,7 @@ static const struct GNUNET_SERVER_MessageHandler defhandlers[] = {
626 * @param uc credentials, if available, otherwise NULL 626 * @param uc credentials, if available, otherwise NULL
627 * @param addr address 627 * @param addr address
628 * @param addrlen length of address 628 * @param addrlen length of address
629 * @return GNUNET_YES to allow, GNUNET_NO to deny, GNUNET_SYSERR 629 * @return #GNUNET_YES to allow, #GNUNET_NO to deny, #GNUNET_SYSERR
630 * for unknown address family (will be denied). 630 * for unknown address family (will be denied).
631 */ 631 */
632static int 632static int
@@ -658,56 +658,7 @@ check_access (void *cls, const struct GNUNET_CONNECTION_Credentials *uc,
658 break; 658 break;
659#ifndef WINDOWS 659#ifndef WINDOWS
660 case AF_UNIX: 660 case AF_UNIX:
661 ret = GNUNET_OK; /* always OK for now */ 661 ret = GNUNET_OK; /* controlled using file-system ACL now */
662 if (GNUNET_YES == sctx->match_uid)
663 {
664 /* UID match required */
665 ret = (NULL != uc) && ( (0 == uc->uid) || (uc->uid == geteuid ()) );
666 }
667 else if ( (GNUNET_YES == sctx->match_gid) &&
668 ( (NULL == uc) ||
669 ( (0 != uc->uid) &&
670 (uc->uid != geteuid ()) ) ) )
671 {
672 /* group match required and UID does not match */
673 if (NULL == uc)
674 {
675 /* no credentials, group match not possible */
676 ret = GNUNET_NO;
677 }
678 else
679 {
680 struct group *grp;
681 unsigned int i;
682
683 if (uc->gid != getegid())
684 {
685 /* default group did not match, but maybe the user is in our group, let's check */
686 grp = getgrgid (getegid ());
687 if (NULL == grp)
688 {
689 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "getgrgid");
690 return GNUNET_NO;
691 }
692 ret = GNUNET_NO;
693 for (i=0; NULL != grp->gr_mem[i]; i++)
694 {
695 struct passwd *nam = getpwnam (grp->gr_mem[i]);
696 if (NULL == nam)
697 continue; /* name in group that is not in user DB !? */
698 if (nam->pw_uid == uc->uid)
699 {
700 /* yes, uid is in our group, allow! */
701 ret = GNUNET_YES;
702 break;
703 }
704 }
705 }
706 }
707 }
708 if (GNUNET_NO == ret)
709 LOG (GNUNET_ERROR_TYPE_WARNING, _("Access denied to UID %d / GID %d\n"),
710 (NULL == uc) ? -1 : uc->uid, (NULL == uc) ? -1 : uc->gid);
711 break; 662 break;
712#endif 663#endif
713 default: 664 default:
@@ -752,7 +703,7 @@ get_pid_file_name (struct GNUNET_SERVICE_Context *sctx)
752 * @param ret location where to write the ACL (set) 703 * @param ret location where to write the ACL (set)
753 * @param sctx service context to use to get the configuration 704 * @param sctx service context to use to get the configuration
754 * @param option name of the ACL option to parse 705 * @param option name of the ACL option to parse
755 * @return GNUNET_SYSERR on parse error, GNUNET_OK on success (including 706 * @return #GNUNET_SYSERR on parse error, #GNUNET_OK on success (including
756 * no ACL configured) 707 * no ACL configured)
757 */ 708 */
758static int 709static int
@@ -789,7 +740,7 @@ process_acl4 (struct IPv4NetworkSet **ret, struct GNUNET_SERVICE_Context *sctx,
789 * @param ret location where to write the ACL (set) 740 * @param ret location where to write the ACL (set)
790 * @param sctx service context to use to get the configuration 741 * @param sctx service context to use to get the configuration
791 * @param option name of the ACL option to parse 742 * @param option name of the ACL option to parse
792 * @return GNUNET_SYSERR on parse error, GNUNET_OK on success (including 743 * @return #GNUNET_SYSERR on parse error, #GNUNET_OK on success (including
793 * no ACL configured) 744 * no ACL configured)
794 */ 745 */
795static int 746static int
@@ -835,7 +786,7 @@ add_unixpath (struct sockaddr **saddrs, socklen_t * saddrlens,
835#ifdef AF_UNIX 786#ifdef AF_UNIX
836 struct sockaddr_un *un; 787 struct sockaddr_un *un;
837 788
838 un = GNUNET_malloc (sizeof (struct sockaddr_un)); 789 un = GNUNET_new (struct sockaddr_un);
839 un->sun_family = AF_UNIX; 790 un->sun_family = AF_UNIX;
840 strncpy (un->sun_path, unixpath, sizeof (un->sun_path) - 1); 791 strncpy (un->sun_path, unixpath, sizeof (un->sun_path) - 1);
841#if HAVE_SOCKADDR_IN_SIN_LEN 792#if HAVE_SOCKADDR_IN_SIN_LEN
@@ -864,11 +815,11 @@ add_unixpath (struct sockaddr **saddrs, socklen_t * saddrlens,
864 * of the respective 'struct sockaddr' struct in the 'addrs' 815 * of the respective 'struct sockaddr' struct in the 'addrs'
865 * array (on success) 816 * array (on success)
866 * @return number of addresses found on success, 817 * @return number of addresses found on success,
867 * GNUNET_SYSERR if the configuration 818 * #GNUNET_SYSERR if the configuration
868 * did not specify reasonable finding information or 819 * did not specify reasonable finding information or
869 * if it specified a hostname that could not be resolved; 820 * if it specified a hostname that could not be resolved;
870 * GNUNET_NO if the number of addresses configured is 821 * #GNUNET_NO if the number of addresses configured is
871 * zero (in this case, '*addrs' and '*addr_lens' will be 822 * zero (in this case, `*addrs` and `*addr_lens` will be
872 * set to NULL). 823 * set to NULL).
873 */ 824 */
874int 825int
@@ -1000,8 +951,7 @@ GNUNET_SERVICE_get_server_addresses (const char *service_name,
1000 return GNUNET_SYSERR; 951 return GNUNET_SYSERR;
1001 } 952 }
1002 LOG (GNUNET_ERROR_TYPE_INFO, 953 LOG (GNUNET_ERROR_TYPE_INFO,
1003 _ 954 _("Disabling UNIX domain socket support for service `%s', failed to create UNIX domain socket: %s\n"),
1004 ("Disabling UNIX domain socket support for service `%s', failed to create UNIX domain socket: %s\n"),
1005 service_name, STRERROR (errno)); 955 service_name, STRERROR (errno));
1006 GNUNET_free (unixpath); 956 GNUNET_free (unixpath);
1007 unixpath = NULL; 957 unixpath = NULL;
@@ -1017,8 +967,7 @@ GNUNET_SERVICE_get_server_addresses (const char *service_name,
1017 if ((0 == port) && (NULL == unixpath)) 967 if ((0 == port) && (NULL == unixpath))
1018 { 968 {
1019 LOG (GNUNET_ERROR_TYPE_ERROR, 969 LOG (GNUNET_ERROR_TYPE_ERROR,
1020 _ 970 _("Have neither PORT nor UNIXPATH for service `%s', but one is required\n"),
1021 ("Have neither PORT nor UNIXPATH for service `%s', but one is required\n"),
1022 service_name); 971 service_name);
1023 GNUNET_free_non_null (hostname); 972 GNUNET_free_non_null (hostname);
1024 return GNUNET_SYSERR; 973 return GNUNET_SYSERR;
@@ -1185,8 +1134,8 @@ GNUNET_SERVICE_get_server_addresses (const char *service_name,
1185 * Read listen sockets from the parent process (ARM). 1134 * Read listen sockets from the parent process (ARM).
1186 * 1135 *
1187 * @param sctx service context to initialize 1136 * @param sctx service context to initialize
1188 * @return GNUNET_YES if ok, GNUNET_NO if not ok (must bind yourself), 1137 * @return #GNUNET_YES if ok, #GNUNET_NO if not ok (must bind yourself),
1189 * and GNUNET_SYSERR on error. 1138 * and #GNUNET_SYSERR on error.
1190 */ 1139 */
1191static int 1140static int
1192receive_sockets_from_parent (struct GNUNET_SERVICE_Context *sctx) 1141receive_sockets_from_parent (struct GNUNET_SERVICE_Context *sctx)
@@ -1280,7 +1229,7 @@ receive_sockets_from_parent (struct GNUNET_SERVICE_Context *sctx)
1280 * - REJECT_FROM6 (disallow allow connections from specified IPv6 subnets) 1229 * - REJECT_FROM6 (disallow allow connections from specified IPv6 subnets)
1281 * 1230 *
1282 * @param sctx service context to initialize 1231 * @param sctx service context to initialize
1283 * @return GNUNET_OK if configuration succeeded 1232 * @return #GNUNET_OK if configuration succeeded
1284 */ 1233 */
1285static int 1234static int
1286setup_service (struct GNUNET_SERVICE_Context *sctx) 1235setup_service (struct GNUNET_SERVICE_Context *sctx)
@@ -1404,12 +1353,13 @@ get_user_name (struct GNUNET_SERVICE_Context *sctx)
1404 return un; 1353 return un;
1405} 1354}
1406 1355
1356
1407/** 1357/**
1408 * Write PID file. 1358 * Write PID file.
1409 * 1359 *
1410 * @param sctx service context 1360 * @param sctx service context
1411 * @param pid PID to write (should be equal to 'getpid()' 1361 * @param pid PID to write (should be equal to 'getpid()'
1412 * @return GNUNET_OK on success (including no work to be done) 1362 * @return #GNUNET_OK on success (including no work to be done)
1413 */ 1363 */
1414static int 1364static int
1415write_pid_file (struct GNUNET_SERVICE_Context *sctx, pid_t pid) 1365write_pid_file (struct GNUNET_SERVICE_Context *sctx, pid_t pid)
@@ -1467,7 +1417,7 @@ write_pid_file (struct GNUNET_SERVICE_Context *sctx, pid_t pid)
1467/** 1417/**
1468 * Task run during shutdown. Stops the server/service. 1418 * Task run during shutdown. Stops the server/service.
1469 * 1419 *
1470 * @param cls the 'struct GNUNET_SERVICE_Context' 1420 * @param cls the `struct GNUNET_SERVICE_Context`
1471 * @param tc unused 1421 * @param tc unused
1472 */ 1422 */
1473static void 1423static void
@@ -1501,33 +1451,37 @@ service_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1501 (void) GNUNET_SPEEDUP_start_ (sctx->cfg); 1451 (void) GNUNET_SPEEDUP_start_ (sctx->cfg);
1502 GNUNET_RESOLVER_connect (sctx->cfg); 1452 GNUNET_RESOLVER_connect (sctx->cfg);
1503 if (NULL != sctx->lsocks) 1453 if (NULL != sctx->lsocks)
1504 sctx->server = 1454 sctx->server
1505 GNUNET_SERVER_create_with_sockets (&check_access, sctx, sctx->lsocks, 1455 = GNUNET_SERVER_create_with_sockets (&check_access, sctx, sctx->lsocks,
1506 sctx->timeout, sctx->require_found); 1456 sctx->timeout, sctx->require_found);
1507 else 1457 else
1508 sctx->server = 1458 sctx->server
1509 GNUNET_SERVER_create (&check_access, sctx, sctx->addrs, sctx->addrlens, 1459 = GNUNET_SERVER_create (&check_access, sctx, sctx->addrs, sctx->addrlens,
1510 sctx->timeout, sctx->require_found); 1460 sctx->timeout, sctx->require_found);
1511 if (NULL == sctx->server) 1461 if (NULL == sctx->server)
1512 { 1462 {
1513 if (NULL != sctx->addrs) 1463 if (NULL != sctx->addrs)
1514 { 1464 for (i = 0; NULL != sctx->addrs[i]; i++)
1515 i = 0; 1465 LOG (GNUNET_ERROR_TYPE_INFO,
1516 while (NULL != sctx->addrs[i]) 1466 _("Failed to start `%s' at `%s'\n"),
1517 {
1518 LOG (GNUNET_ERROR_TYPE_INFO, _("Failed to start `%s' at `%s'\n"),
1519 sctx->service_name, GNUNET_a2s (sctx->addrs[i], sctx->addrlens[i])); 1467 sctx->service_name, GNUNET_a2s (sctx->addrs[i], sctx->addrlens[i]));
1520 i++;
1521 }
1522 }
1523 sctx->ret = GNUNET_SYSERR; 1468 sctx->ret = GNUNET_SYSERR;
1524 return; 1469 return;
1525 } 1470 }
1471 if (NULL != sctx->addrs)
1472 for (i = 0; NULL != sctx->addrs[i]; i++)
1473 if (AF_UNIX == sctx->addrs[i]->sa_family)
1474 GNUNET_DISK_fix_permissions (((const struct sockaddr_un *)sctx->addrs[i])->sun_path,
1475 sctx->match_uid,
1476 sctx->match_gid);
1477
1478
1526 if (0 == (sctx->options & GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN)) 1479 if (0 == (sctx->options & GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN))
1527 { 1480 {
1528 /* install a task that will kill the server 1481 /* install a task that will kill the server
1529 * process if the scheduler ever gets a shutdown signal */ 1482 * process if the scheduler ever gets a shutdown signal */
1530 sctx->shutdown_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task, 1483 sctx->shutdown_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
1484 &shutdown_task,
1531 sctx); 1485 sctx);
1532 } 1486 }
1533 sctx->my_handlers = GNUNET_malloc (sizeof (defhandlers)); 1487 sctx->my_handlers = GNUNET_malloc (sizeof (defhandlers));
@@ -1642,7 +1596,7 @@ detach_terminal (struct GNUNET_SERVICE_Context *sctx)
1642 * Set user ID. 1596 * Set user ID.
1643 * 1597 *
1644 * @param sctx service context 1598 * @param sctx service context
1645 * @return GNUNET_OK on success, GNUNET_SYSERR on error 1599 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
1646 */ 1600 */
1647static int 1601static int
1648set_user_id (struct GNUNET_SERVICE_Context *sctx) 1602set_user_id (struct GNUNET_SERVICE_Context *sctx)
@@ -1717,8 +1671,10 @@ pid_file_delete (struct GNUNET_SERVICE_Context *sctx)
1717 * if we shutdown nicely 1671 * if we shutdown nicely
1718 */ 1672 */
1719int 1673int
1720GNUNET_SERVICE_run (int argc, char *const *argv, const char *service_name, 1674GNUNET_SERVICE_run (int argc, char *const *argv,
1721 enum GNUNET_SERVICE_Options options, GNUNET_SERVICE_Main task, 1675 const char *service_name,
1676 enum GNUNET_SERVICE_Options options,
1677 GNUNET_SERVICE_Main task,
1722 void *task_cls) 1678 void *task_cls)
1723{ 1679{
1724#define HANDLE_ERROR do { GNUNET_break (0); goto shutdown; } while (0) 1680#define HANDLE_ERROR do { GNUNET_break (0); goto shutdown; } while (0)
@@ -1891,7 +1847,7 @@ GNUNET_SERVICE_start (const char *service_name,
1891 int i; 1847 int i;
1892 struct GNUNET_SERVICE_Context *sctx; 1848 struct GNUNET_SERVICE_Context *sctx;
1893 1849
1894 sctx = GNUNET_malloc (sizeof (struct GNUNET_SERVICE_Context)); 1850 sctx = GNUNET_new (struct GNUNET_SERVICE_Context);
1895 sctx->ready_confirm_fd = -1; /* no daemonizing */ 1851 sctx->ready_confirm_fd = -1; /* no daemonizing */
1896 sctx->ret = GNUNET_OK; 1852 sctx->ret = GNUNET_OK;
1897 sctx->timeout = GNUNET_TIME_UNIT_FOREVER_REL; 1853 sctx->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
@@ -1919,6 +1875,12 @@ GNUNET_SERVICE_start (const char *service_name,
1919 GNUNET_SERVICE_stop (sctx); 1875 GNUNET_SERVICE_stop (sctx);
1920 return NULL; 1876 return NULL;
1921 } 1877 }
1878 if (NULL != sctx->addrs)
1879 for (i = 0; NULL != sctx->addrs[i]; i++)
1880 if (AF_UNIX == sctx->addrs[i]->sa_family)
1881 GNUNET_DISK_fix_permissions (((const struct sockaddr_un *)sctx->addrs[i])->sun_path,
1882 sctx->match_uid,
1883 sctx->match_gid);
1922 sctx->my_handlers = GNUNET_malloc (sizeof (defhandlers)); 1884 sctx->my_handlers = GNUNET_malloc (sizeof (defhandlers));
1923 memcpy (sctx->my_handlers, defhandlers, sizeof (defhandlers)); 1885 memcpy (sctx->my_handlers, defhandlers, sizeof (defhandlers));
1924 i = 0; 1886 i = 0;