diff options
-rw-r--r-- | src/arm/gnunet-service-arm.c | 97 | ||||
-rw-r--r-- | src/include/gnunet_disk_lib.h | 17 | ||||
-rw-r--r-- | src/util/connection.c | 3 | ||||
-rw-r--r-- | src/util/disk.c | 29 | ||||
-rw-r--r-- | src/util/network.c | 37 | ||||
-rw-r--r-- | src/util/server.c | 16 | ||||
-rw-r--r-- | src/util/service.c | 138 |
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 | */ |
270 | int | 270 | int |
271 | GNUNET_DISK_handle_invalid (const struct GNUNET_DISK_FileHandle *h); | 271 | GNUNET_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 | */ |
507 | struct GNUNET_DISK_FileHandle * | 507 | struct GNUNET_DISK_FileHandle * |
508 | GNUNET_DISK_get_handle_from_w32_handle (HANDLE osfh); | 508 | GNUNET_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 | */ | ||
519 | void | ||
520 | GNUNET_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 | */ | ||
476 | void | ||
477 | GNUNET_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 | */ |
394 | static void | 394 | static void |
395 | process_listen_socket (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 395 | process_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 | */ |
440 | static struct GNUNET_NETWORK_Handle * | 442 | static 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 | */ |
632 | static int | 632 | static 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 | */ |
758 | static int | 709 | static 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 | */ |
795 | static int | 746 | static 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 | */ |
874 | int | 825 | int |
@@ -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 | */ |
1191 | static int | 1140 | static int |
1192 | receive_sockets_from_parent (struct GNUNET_SERVICE_Context *sctx) | 1141 | receive_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 | */ |
1285 | static int | 1234 | static int |
1286 | setup_service (struct GNUNET_SERVICE_Context *sctx) | 1235 | setup_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 | */ |
1414 | static int | 1364 | static int |
1415 | write_pid_file (struct GNUNET_SERVICE_Context *sctx, pid_t pid) | 1365 | write_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 | */ |
1473 | static void | 1423 | static 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 | */ |
1647 | static int | 1601 | static int |
1648 | set_user_id (struct GNUNET_SERVICE_Context *sctx) | 1602 | set_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 | */ |
1719 | int | 1673 | int |
1720 | GNUNET_SERVICE_run (int argc, char *const *argv, const char *service_name, | 1674 | GNUNET_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; |