summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2007-06-13 20:52:58 +0000
committerHavoc Pennington <hp@redhat.com>2007-06-13 20:52:58 +0000
commit72697649524238bd8389670e71c9faa55b7b4a1a (patch)
treee6c3ad0d6b7070e8f0cfd00231a5bbad739bb363
parente3d30a03225dd1d26012ecd39b09e4ccf91befb5 (diff)
2007-06-13 Havoc Pennington <hp@redhat.com>
* dbus/dbus-server-socket.c (_dbus_server_listen_socket): support all_interfaces=true|false for tcp servers * dbus/dbus-sysdeps-unix.c (_dbus_listen_tcp_socket): support inaddr_any flag * bus/selinux.c: fix some missing includes * dbus/dbus-server-socket.c (_dbus_server_listen_socket): allow port to simply be omitted in addition to specifying 0
-rw-r--r--ChangeLog13
-rw-r--r--bus/dbus-daemon.1.in15
-rw-r--r--bus/selinux.c3
-rw-r--r--dbus/dbus-server-socket.c76
-rw-r--r--dbus/dbus-server-socket.h1
-rw-r--r--dbus/dbus-sysdeps-unix.c54
-rw-r--r--dbus/dbus-sysdeps.h1
7 files changed, 117 insertions, 46 deletions
diff --git a/ChangeLog b/ChangeLog
index 26e97849..88070a94 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,18 @@
2007-06-13 Havoc Pennington <hp@redhat.com>
+ * dbus/dbus-server-socket.c (_dbus_server_listen_socket): support
+ all_interfaces=true|false for tcp servers
+
+ * dbus/dbus-sysdeps-unix.c (_dbus_listen_tcp_socket): support
+ inaddr_any flag
+
+ * bus/selinux.c: fix some missing includes
+
+ * dbus/dbus-server-socket.c (_dbus_server_listen_socket): allow
+ port to simply be omitted in addition to specifying 0
+
+2007-06-13 Havoc Pennington <hp@redhat.com>
+
* configure.ac, bus/selinux.c, dbus/dbus-sysdeps-unix-util.c: add
libaudit support, no clue what this means really but now we have
it. Patches from Fedora package.
diff --git a/bus/dbus-daemon.1.in b/bus/dbus-daemon.1.in
index a657d285..ce623f8b 100644
--- a/bus/dbus-daemon.1.in
+++ b/bus/dbus-daemon.1.in
@@ -221,13 +221,22 @@ the last address given in <listen> first. That is,
apps will try to connect to the last <listen> address first.
.PP
-A special case is using a port number of zero which means to
-pick up a random free port. The real used port number could be retrieved
-by using the --print-address command line parameter.
+A special case is using a port number of zero (or omitting the port),
+which means to choose an available port selected by the operating
+system. The port number chosen can be with the --print-address command
+line parameter and will be present in other cases where the server
+reports its own address, such as when DBUS_SESSION_BUS_ADDRESS is set.
.PP
Example: <listen>tcp:host=localhost,port=0</listen>
+.PP
+tcp addresses also allow an all_interfaces=true option, which will
+cause the bus to listen on all local address (INADDR_ANY) and not only
+the specified host. However, the specified host will still be used as
+the reported address of the server. The specified host should be a
+valid name of the local machine or weird stuff will happen.
+
.TP
.I "<auth>"
diff --git a/bus/selinux.c b/bus/selinux.c
index c2138380..a37e367a 100644
--- a/bus/selinux.c
+++ b/bus/selinux.c
@@ -29,6 +29,8 @@
#include "config-parser.h"
#ifdef HAVE_SELINUX
+#include <sys/types.h>
+#include <unistd.h>
#include <errno.h>
#include <pthread.h>
#include <syslog.h>
@@ -38,6 +40,7 @@
#include <selinux/flask.h>
#include <signal.h>
#include <stdarg.h>
+#include <stdio.h>
#ifdef HAVE_LIBAUDIT
#include <libaudit.h>
#endif /* HAVE_LIBAUDIT */
diff --git a/dbus/dbus-server-socket.c b/dbus/dbus-server-socket.c
index 3a0da35f..e6fd7d58 100644
--- a/dbus/dbus-server-socket.c
+++ b/dbus/dbus-server-socket.c
@@ -295,17 +295,24 @@ _dbus_server_new_for_socket (int fd,
}
/**
- * Creates a new server listening on the given hostname and port.
- * If the hostname is NULL, listens on localhost.
+ * Creates a new server listening on TCP.
+ * If inaddr_any is TRUE, listens on all local interfaces.
+ * Otherwise, it resolves the hostname and listens only on
+ * the resolved address of the hostname. The hostname is used
+ * even if inaddr_any is TRUE, as the hostname to report when
+ * dbus_server_get_address() is called. If the hostname is #NULL,
+ * localhost is used.
*
* @param host the hostname to listen on.
- * @param port the port to listen on.
+ * @param port the port to listen on or 0 to let the OS choose
+ * @param inaddr_any #TRUE to listen on all local interfaces
* @param error location to store reason for failure.
* @returns the new server, or #NULL on failure.
*/
DBusServer*
_dbus_server_new_for_tcp_socket (const char *host,
dbus_uint32_t port,
+ dbus_bool_t inaddr_any,
DBusError *error)
{
DBusServer *server;
@@ -324,7 +331,7 @@ _dbus_server_new_for_tcp_socket (const char *host,
if (host == NULL)
host = "localhost";
- listen_fd = _dbus_listen_tcp_socket (host, &port, error);
+ listen_fd = _dbus_listen_tcp_socket (host, &port, inaddr_any, error);
_dbus_fd_set_close_on_exec (listen_fd);
_dbus_string_init_const (&host_str, host);
@@ -386,30 +393,57 @@ _dbus_server_listen_socket (DBusAddressEntry *entry,
if (strcmp (method, "tcp") == 0)
{
- const char *host = dbus_address_entry_get_value (entry, "host");
- const char *port = dbus_address_entry_get_value (entry, "port");
- DBusString str;
+ const char *host;
+ const char *port;
+ const char *all_interfaces;
+ dbus_bool_t inaddr_any;
long lport;
- dbus_bool_t sresult;
-
+
+ host = dbus_address_entry_get_value (entry, "host");
+ port = dbus_address_entry_get_value (entry, "port");
+ all_interfaces = dbus_address_entry_get_value (entry, "all_interfaces");
+
+ inaddr_any = FALSE;
+ if (all_interfaces != NULL)
+ {
+ if (strcmp (all_interfaces, "true") == 0)
+ {
+ inaddr_any = TRUE;
+ }
+ else if (strcmp (all_interfaces, "false") == 0)
+ {
+ inaddr_any = FALSE;
+ }
+ else
+ {
+ _dbus_set_bad_address(error, NULL, NULL,
+ "all_interfaces flag in tcp: address should be 'true' or 'false'");
+ return DBUS_SERVER_LISTEN_BAD_ADDRESS;
+ }
+ }
+
if (port == NULL)
{
- _dbus_set_bad_address(error, "tcp", "port", NULL);
- return DBUS_SERVER_LISTEN_BAD_ADDRESS;
+ lport = 0;
}
-
- _dbus_string_init_const (&str, port);
- sresult = _dbus_string_parse_int (&str, 0, &lport, NULL);
- _dbus_string_free (&str);
-
- if (sresult == FALSE || lport < 0 || lport > 65535)
+ else
{
- _dbus_set_bad_address(error, NULL, NULL,
- "Port is not an integer between 0 and 65535");
- return DBUS_SERVER_LISTEN_BAD_ADDRESS;
+ dbus_bool_t sresult;
+ DBusString str;
+
+ _dbus_string_init_const (&str, port);
+ sresult = _dbus_string_parse_int (&str, 0, &lport, NULL);
+ _dbus_string_free (&str);
+
+ if (sresult == FALSE || lport < 0 || lport > 65535)
+ {
+ _dbus_set_bad_address(error, NULL, NULL,
+ "Port is not an integer between 0 and 65535");
+ return DBUS_SERVER_LISTEN_BAD_ADDRESS;
+ }
}
- *server_p = _dbus_server_new_for_tcp_socket (host, lport, error);
+ *server_p = _dbus_server_new_for_tcp_socket (host, lport, inaddr_any, error);
if (*server_p)
{
diff --git a/dbus/dbus-server-socket.h b/dbus/dbus-server-socket.h
index 384098e2..176304fc 100644
--- a/dbus/dbus-server-socket.h
+++ b/dbus/dbus-server-socket.h
@@ -32,6 +32,7 @@ DBusServer* _dbus_server_new_for_socket (int fd,
const DBusString *address);
DBusServer* _dbus_server_new_for_tcp_socket (const char *host,
dbus_uint32_t port,
+ dbus_bool_t inaddr_any,
DBusError *error);
DBusServerListenResult _dbus_server_listen_socket (DBusAddressEntry *entry,
DBusServer **server_p,
diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c
index f1c133fd..b3ffe04f 100644
--- a/dbus/dbus-sysdeps-unix.c
+++ b/dbus/dbus-sysdeps-unix.c
@@ -807,30 +807,28 @@ _dbus_connect_tcp_socket (const char *host,
}
/**
- * Creates a socket and binds it to the given path,
- * then listens on the socket. The socket is
- * set to be nonblocking.
- * In case of port=0 a random free port is used and
- * returned in the port parameter.
+ * Creates a socket and binds it to the given path, then listens on
+ * the socket. The socket is set to be nonblocking. In case of port=0
+ * a random free port is used and returned in the port parameter.
+ * If inaddr_any is specified, the hostname is ignored.
*
* @param host the host name to listen on
- * @param port the prot to listen on, if zero a free port will be used
+ * @param port the prot to listen on, if zero a free port will be used
+ * @param inaddr_any TRUE to listen on all local interfaces instead of on the host name
* @param error return location for errors
* @returns the listening file descriptor or -1 on error
*/
int
_dbus_listen_tcp_socket (const char *host,
dbus_uint32_t *port,
+ dbus_bool_t inaddr_any,
DBusError *error)
{
int listen_fd;
struct sockaddr_in addr;
- struct hostent *he;
- struct in_addr *haddr;
socklen_t len = (socklen_t) sizeof (struct sockaddr);
- _DBUS_ASSERT_ERROR_IS_CLEAR (error);
-
+ _DBUS_ASSERT_ERROR_IS_CLEAR (error);
if (!_dbus_open_tcp_socket (&listen_fd, error))
{
@@ -839,21 +837,33 @@ _dbus_listen_tcp_socket (const char *host,
}
_DBUS_ASSERT_ERROR_IS_CLEAR(error);
- he = gethostbyname (host);
- if (he == NULL)
+ _DBUS_ZERO (addr);
+
+ if (inaddr_any)
{
- dbus_set_error (error,
- _dbus_error_from_errno (errno),
- "Failed to lookup hostname: %s",
- host);
- _dbus_close (listen_fd, NULL);
- return -1;
+ addr.sin_addr.s_addr = INADDR_ANY;
}
-
- haddr = ((struct in_addr *) (he->h_addr_list)[0]);
+ else
+ {
+ struct hostent *he;
+ struct in_addr *haddr;
- _DBUS_ZERO (addr);
- memcpy (&addr.sin_addr, haddr, sizeof (struct in_addr));
+ he = gethostbyname (host);
+ if (he == NULL)
+ {
+ dbus_set_error (error,
+ _dbus_error_from_errno (errno),
+ "Failed to lookup hostname: %s",
+ host);
+ _dbus_close (listen_fd, NULL);
+ return -1;
+ }
+
+ haddr = ((struct in_addr *) (he->h_addr_list)[0]);
+
+ memcpy (&addr.sin_addr, haddr, sizeof (struct in_addr));
+ }
+
addr.sin_family = AF_INET;
addr.sin_port = htons (*port);
diff --git a/dbus/dbus-sysdeps.h b/dbus/dbus-sysdeps.h
index 87bfc8fa..0cb92c61 100644
--- a/dbus/dbus-sysdeps.h
+++ b/dbus/dbus-sysdeps.h
@@ -151,6 +151,7 @@ int _dbus_connect_tcp_socket (const char *host,
DBusError *error);
int _dbus_listen_tcp_socket (const char *host,
dbus_uint32_t *port,
+ dbus_bool_t inaddr_any,
DBusError *error);
int _dbus_accept (int listen_fd);