summaryrefslogtreecommitdiffstats
path: root/bus
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2003-04-01 05:33:01 +0000
committerHavoc Pennington <hp@redhat.com>2003-04-01 05:33:01 +0000
commit44ed933284589134603913b05f55ca55e8c5a566 (patch)
tree7091c28eba6a2d93cd02ca80c39b3175ccca06f5 /bus
parent8dfe82beb530aefce505a9bf915a749647e7183f (diff)
2003-04-01 Havoc Pennington <hp@pobox.com>
* dbus/dbus-server.c (dbus_server_set_auth_mechanisms): new function * dbus/dbus-auth.c (_dbus_auth_set_mechanisms): new * dbus/dbus-internals.c (_dbus_dup_string_array): new function * dbus/dbus-sysdeps.c (_dbus_listen_unix_socket): chmod the socket 0777, and unlink any existing socket. * bus/bus.c (bus_context_new): change our UID/GID and fork if the configuration file so specifies; set up auth mechanism restrictions * bus/config-parser.c (bus_config_parser_content): add support for <fork> option and fill in code for <auth> * bus/system.conf.in: add <fork/> to default configuration, and limit auth mechanisms to EXTERNAL * doc/config-file.txt (Elements): add <fork> * dbus/dbus-sysdeps.c (_dbus_become_daemon): new function (_dbus_change_identity): new function
Diffstat (limited to 'bus')
-rw-r--r--bus/bus.c84
-rw-r--r--bus/config-parser.c70
-rw-r--r--bus/config-parser.h6
-rw-r--r--bus/system.conf.in20
4 files changed, 171 insertions, 9 deletions
diff --git a/bus/bus.c b/bus/bus.c
index ca9802c0..1ca4feb8 100644
--- a/bus/bus.c
+++ b/bus/bus.c
@@ -141,8 +141,15 @@ free_rule_list_func (void *data)
static dbus_bool_t
setup_server (BusContext *context,
DBusServer *server,
+ char **auth_mechanisms,
DBusError *error)
-{
+{
+ if (!dbus_server_set_auth_mechanisms (server, (const char**) auth_mechanisms))
+ {
+ BUS_SET_OOM (error);
+ return FALSE;
+ }
+
dbus_server_set_new_connection_function (server,
new_connection_callback,
context, NULL);
@@ -181,6 +188,10 @@ bus_context_new (const DBusString *config_file,
BusConfigParser *parser;
DBusString full_address;
const char *service_dirs[] = { NULL, NULL };
+ const char *user;
+ char **auth_mechanisms;
+ DBusList **auth_mechanisms_list;
+ int len;
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
@@ -189,6 +200,7 @@ bus_context_new (const DBusString *config_file,
parser = NULL;
context = NULL;
+ auth_mechanisms = NULL;
parser = bus_config_load (config_file, error);
if (parser == NULL)
@@ -202,6 +214,36 @@ bus_context_new (const DBusString *config_file,
}
context->refcount = 1;
+
+ /* Build an array of auth mechanisms */
+
+ auth_mechanisms_list = bus_config_parser_get_mechanisms (parser);
+ len = _dbus_list_get_length (auth_mechanisms_list);
+
+ if (len > 0)
+ {
+ int i;
+
+ auth_mechanisms = dbus_new0 (char*, len + 1);
+ if (auth_mechanisms == NULL)
+ goto failed;
+
+ i = 0;
+ link = _dbus_list_get_first_link (auth_mechanisms_list);
+ while (link != NULL)
+ {
+ auth_mechanisms[i] = _dbus_strdup (link->data);
+ if (auth_mechanisms[i] == NULL)
+ goto failed;
+ link = _dbus_list_get_next_link (auth_mechanisms_list, link);
+ }
+ }
+ else
+ {
+ auth_mechanisms = NULL;
+ }
+
+ /* Listen on our addresses */
addresses = bus_config_parser_get_addresses (parser);
@@ -213,7 +255,7 @@ bus_context_new (const DBusString *config_file,
server = dbus_server_listen (link->data, error);
if (server == NULL)
goto failed;
- else if (!setup_server (context, server, error))
+ else if (!setup_server (context, server, auth_mechanisms, error))
goto failed;
if (!_dbus_list_append (&context->servers, server))
@@ -225,6 +267,31 @@ bus_context_new (const DBusString *config_file,
link = _dbus_list_get_next_link (addresses, link);
}
+ /* Here we change our credentials if required,
+ * as soon as we've set up our sockets
+ */
+ user = bus_config_parser_get_user (parser);
+ if (user != NULL)
+ {
+ DBusCredentials creds;
+ DBusString u;
+
+ _dbus_string_init_const (&u, user);
+
+ if (!_dbus_credentials_from_username (&u, &creds) ||
+ creds.uid < 0 ||
+ creds.gid < 0)
+ {
+ dbus_set_error (error, DBUS_ERROR_FAILED,
+ "Could not get UID and GID for username \"%s\"",
+ user);
+ goto failed;
+ }
+
+ if (!_dbus_change_identity (creds.uid, creds.gid, error))
+ goto failed;
+ }
+
/* We have to build the address backward, so that
* <listen> later in the config file have priority
*/
@@ -265,6 +332,8 @@ bus_context_new (const DBusString *config_file,
BUS_SET_OOM (error);
goto failed;
}
+
+ /* Create activation subsystem */
context->activation = bus_activation_new (context, &full_address,
service_dirs, error);
@@ -306,12 +375,20 @@ bus_context_new (const DBusString *config_file,
goto failed;
}
+ /* Now become a daemon if appropriate */
+ if (bus_config_parser_get_fork (parser))
+ {
+ if (!_dbus_become_daemon (error))
+ goto failed;
+ }
+
bus_config_parser_unref (parser);
_dbus_string_free (&full_address);
+ dbus_free_string_array (auth_mechanisms);
return context;
- failed:
+ failed:
if (parser != NULL)
bus_config_parser_unref (parser);
@@ -319,6 +396,7 @@ bus_context_new (const DBusString *config_file,
bus_context_unref (context);
_dbus_string_free (&full_address);
+ dbus_free_string_array (auth_mechanisms);
return NULL;
}
diff --git a/bus/config-parser.c b/bus/config-parser.c
index 39239888..dc3cb4d6 100644
--- a/bus/config-parser.c
+++ b/bus/config-parser.c
@@ -37,7 +37,8 @@ typedef enum
ELEMENT_POLICY,
ELEMENT_LIMIT,
ELEMENT_ALLOW,
- ELEMENT_DENY
+ ELEMENT_DENY,
+ ELEMENT_FORK
} ElementType;
typedef struct
@@ -84,6 +85,10 @@ struct BusConfigParser
char *user; /**< user to run as */
DBusList *listen_on; /**< List of addresses to listen to */
+
+ DBusList *mechanisms; /**< Auth mechanisms */
+
+ unsigned int fork : 1; /**< TRUE to fork into daemon mode */
};
static const char*
@@ -111,6 +116,8 @@ element_type_to_name (ElementType type)
return "allow";
case ELEMENT_DENY:
return "deny";
+ case ELEMENT_FORK:
+ return "fork";
}
_dbus_assert_not_reached ("bad element type");
@@ -195,9 +202,15 @@ merge_included (BusConfigParser *parser,
included->user = NULL;
}
+ if (included->fork)
+ parser->fork = TRUE;
+
while ((link = _dbus_list_pop_first_link (&included->listen_on)))
_dbus_list_append_link (&parser->listen_on, link);
+ while ((link = _dbus_list_pop_first_link (&included->mechanisms)))
+ _dbus_list_append_link (&parser->mechanisms, link);
+
return TRUE;
}
@@ -409,6 +422,21 @@ start_busconfig_child (BusConfigParser *parser,
return TRUE;
}
+ else if (strcmp (element_name, "fork") == 0)
+ {
+ if (!check_no_attributes (parser, "fork", attribute_names, attribute_values, error))
+ return FALSE;
+
+ if (push_element (parser, ELEMENT_FORK) == NULL)
+ {
+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+ return FALSE;
+ }
+
+ parser->fork = TRUE;
+
+ return TRUE;
+ }
else if (strcmp (element_name, "listen") == 0)
{
if (!check_no_attributes (parser, "listen", attribute_names, attribute_values, error))
@@ -422,6 +450,19 @@ start_busconfig_child (BusConfigParser *parser,
return TRUE;
}
+ else if (strcmp (element_name, "auth") == 0)
+ {
+ if (!check_no_attributes (parser, "auth", attribute_names, attribute_values, error))
+ return FALSE;
+
+ if (push_element (parser, ELEMENT_AUTH) == NULL)
+ {
+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+ return FALSE;
+ }
+
+ return TRUE;
+ }
else if (strcmp (element_name, "include") == 0)
{
Element *e;
@@ -654,6 +695,7 @@ bus_config_parser_end_element (BusConfigParser *parser,
case ELEMENT_LIMIT:
case ELEMENT_ALLOW:
case ELEMENT_DENY:
+ case ELEMENT_FORK:
break;
}
@@ -715,6 +757,7 @@ bus_config_parser_content (BusConfigParser *parser,
case ELEMENT_LIMIT:
case ELEMENT_ALLOW:
case ELEMENT_DENY:
+ case ELEMENT_FORK:
if (all_whitespace (content))
return TRUE;
else
@@ -800,8 +843,19 @@ bus_config_parser_content (BusConfigParser *parser,
case ELEMENT_AUTH:
{
+ char *s;
+
e->had_content = TRUE;
- /* FIXME */
+
+ if (!_dbus_string_copy_data (content, &s))
+ goto nomem;
+
+ if (!_dbus_list_append (&parser->mechanisms,
+ s))
+ {
+ dbus_free (s);
+ goto nomem;
+ }
}
break;
}
@@ -851,6 +905,18 @@ bus_config_parser_get_addresses (BusConfigParser *parser)
return &parser->listen_on;
}
+DBusList**
+bus_config_parser_get_mechanisms (BusConfigParser *parser)
+{
+ return &parser->mechanisms;
+}
+
+dbus_bool_t
+bus_config_parser_get_fork (BusConfigParser *parser)
+{
+ return parser->fork;
+}
+
#ifdef DBUS_BUILD_TESTS
#include <stdio.h>
diff --git a/bus/config-parser.h b/bus/config-parser.h
index 8c66fa63..101b4c6f 100644
--- a/bus/config-parser.h
+++ b/bus/config-parser.h
@@ -55,8 +55,10 @@ dbus_bool_t bus_config_parser_finished (BusConfigParser *parser,
DBusError *error);
/* Functions for extracting the parse results */
-const char* bus_config_parser_get_user (BusConfigParser *parser);
-DBusList** bus_config_parser_get_addresses (BusConfigParser *parser);
+const char* bus_config_parser_get_user (BusConfigParser *parser);
+DBusList** bus_config_parser_get_addresses (BusConfigParser *parser);
+DBusList** bus_config_parser_get_mechanisms (BusConfigParser *parser);
+dbus_bool_t bus_config_parser_get_fork (BusConfigParser *parser);
/* Loader functions (backended off one of the XML parsers). Returns a
* finished ConfigParser.
diff --git a/bus/system.conf.in b/bus/system.conf.in
index fe4e049a..7752b576 100644
--- a/bus/system.conf.in
+++ b/bus/system.conf.in
@@ -2,13 +2,29 @@
Add a system-local.conf and edit that rather than changing this
file directly. -->
+<!-- Note that there are any number of ways you can hose yourself
+ security-wise by screwing up this file; in particular, you
+ probably don't want to listen on any more addresses, add any more
+ auth mechanisms, run as a different user, etc. -->
+
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
- <user>fixme</user>
+
+ <!-- Run as special user -->
+ <user>messagebus</user>
+
+ <!-- Fork into daemon mode -->
+ <fork/>
+
+ <!-- Only allow socket-credentials-based authentication -->
+ <auth>EXTERNAL</auth>
+
+ <!-- Only listen on a local socket -->
<listen>unix:path=@EXPANDED_LOCALSTATEDIR@/@DBUS_SYSTEM_SOCKET@</listen>
+
<policy context="default">
- <!-- Deny everything -->
+ <!-- Deny everything then punch holes -->
<deny send="*"/>
<deny receive="*"/>
<deny own="*"/>