Commit 935a41a0 authored by Colin Walters's avatar Colin Walters

2004-11-09 Colin Walters <walters@verbum.org>

	* dbus/dbus-string.c (_dbus_string_get_length): New
	function, writes DBusString to C buffer.

	* dbus/dbus-string.h: Prototype it.

	* dbus/dbus-message.c (dbus_message_type_to_string): New
	function, converts message type into C string.

	* dbus/dbus-message.h: Prototype it.

	* bus/selinux.c (bus_selinux_check): Take source pid,
	target pid, and audit data.  Pass audit data to
	avc_has_perm.
	(log_audit_callback): New function, appends extra
	audit information.
	(bus_selinux_allows_acquire_service): Also take
	service name, add it to audit data.
	(bus_selinux_allows_send): Also take message
	type, interface, method member, error name,
	and destination, and add them to audit data.
	(log_cb): Initialize func_audit.

	* bus/selinux.h (bus_selinux_allows_acquire_service)
	(bus_selinux_allows_send): Update prototypes

	* bus/services.c (bus_registry_acquire_service): Pass
	service name to bus_selinux_allows_acquire_service.

	* bus/bus.c (bus_context_check_security_policy): Pass
	additional audit data.  Move assignment of dest
	to its own line.
parent 2f5e9498
2004-11-09 Colin Walters <walters@verbum.org>
* dbus/dbus-string.c (_dbus_string_get_length): New
function, writes DBusString to C buffer.
* dbus/dbus-string.h: Prototype it.
* dbus/dbus-message.c (dbus_message_type_to_string): New
function, converts message type into C string.
* dbus/dbus-message.h: Prototype it.
* bus/selinux.c (bus_selinux_check): Take source pid,
target pid, and audit data. Pass audit data to
avc_has_perm.
(log_audit_callback): New function, appends extra
audit information.
(bus_selinux_allows_acquire_service): Also take
service name, add it to audit data.
(bus_selinux_allows_send): Also take message
type, interface, method member, error name,
and destination, and add them to audit data.
(log_cb): Initialize func_audit.
* bus/selinux.h (bus_selinux_allows_acquire_service)
(bus_selinux_allows_send): Update prototypes
* bus/services.c (bus_registry_acquire_service): Pass
service name to bus_selinux_allows_acquire_service.
* bus/bus.c (bus_context_check_security_policy): Pass
additional audit data. Move assignment of dest
to its own line.
2004-11-07 Colin Walters <walters@verbum.org> 2004-11-07 Colin Walters <walters@verbum.org>
* dbus/dbus-transport-unix.c (do_authentication): Always * dbus/dbus-transport-unix.c (do_authentication): Always
......
...@@ -1127,12 +1127,20 @@ bus_context_check_security_policy (BusContext *context, ...@@ -1127,12 +1127,20 @@ bus_context_check_security_policy (BusContext *context,
if (sender != NULL) if (sender != NULL)
{ {
const char *dest;
dest = dbus_message_get_destination (message);
/* First verify the SELinux access controls. If allowed then /* First verify the SELinux access controls. If allowed then
* go on with the standard checks. * go on with the standard checks.
*/ */
if (!bus_selinux_allows_send (sender, proposed_recipient)) if (!bus_selinux_allows_send (sender, proposed_recipient,
dbus_message_type_to_string (dbus_message_get_type (message)),
dbus_message_get_interface (message),
dbus_message_get_member (message),
dbus_message_get_error_name (message),
dest ? dest : DBUS_SERVICE_ORG_FREEDESKTOP_DBUS))
{ {
const char *dest = dbus_message_get_destination (message);
dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED, dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
"An SELinux policy prevents this sender " "An SELinux policy prevents this sender "
"from sending this message to this recipient " "from sending this message to this recipient "
...@@ -1255,7 +1263,9 @@ bus_context_check_security_policy (BusContext *context, ...@@ -1255,7 +1263,9 @@ bus_context_check_security_policy (BusContext *context,
proposed_recipient, proposed_recipient,
message)) message))
{ {
const char *dest = dbus_message_get_destination (message); const char *dest;
dest = dbus_message_get_destination (message);
dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED, dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
"A security policy in place prevents this sender " "A security policy in place prevents this sender "
"from sending this message to this recipient, " "from sending this message to this recipient, "
...@@ -1280,7 +1290,9 @@ bus_context_check_security_policy (BusContext *context, ...@@ -1280,7 +1290,9 @@ bus_context_check_security_policy (BusContext *context,
addressed_recipient, proposed_recipient, addressed_recipient, proposed_recipient,
message)) message))
{ {
const char *dest = dbus_message_get_destination (message); const char *dest;
dest = dbus_message_get_destination (message);
dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED, dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
"A security policy in place prevents this recipient " "A security policy in place prevents this recipient "
"from receiving this message from this sender, " "from receiving this message from this sender, "
...@@ -1304,7 +1316,9 @@ bus_context_check_security_policy (BusContext *context, ...@@ -1304,7 +1316,9 @@ bus_context_check_security_policy (BusContext *context,
dbus_connection_get_outgoing_size (proposed_recipient) > dbus_connection_get_outgoing_size (proposed_recipient) >
context->limits.max_outgoing_bytes) context->limits.max_outgoing_bytes)
{ {
const char *dest = dbus_message_get_destination (message); const char *dest;
dest = dbus_message_get_destination (message);
dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED, dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
"The destination service \"%s\" has a full message queue", "The destination service \"%s\" has a full message queue",
dest ? dest : (proposed_recipient ? dest ? dest : (proposed_recipient ?
......
...@@ -57,6 +57,7 @@ static pthread_t avc_notify_thread; ...@@ -57,6 +57,7 @@ static pthread_t avc_notify_thread;
/* Prototypes for AVC callback functions. */ /* Prototypes for AVC callback functions. */
static void log_callback (const char *fmt, ...); static void log_callback (const char *fmt, ...);
static void log_audit_callback (void *data, security_class_t class, char *buf, size_t bufleft);
static void *avc_create_thread (void (*run) (void)); static void *avc_create_thread (void (*run) (void));
static void avc_stop_thread (void *thread); static void avc_stop_thread (void *thread);
static void *avc_alloc_lock (void); static void *avc_alloc_lock (void);
...@@ -73,7 +74,7 @@ static const struct avc_memory_callback mem_cb = ...@@ -73,7 +74,7 @@ static const struct avc_memory_callback mem_cb =
static const struct avc_log_callback log_cb = static const struct avc_log_callback log_cb =
{ {
.func_log = log_callback, .func_log = log_callback,
.func_audit = NULL .func_audit = log_audit_callback
}; };
static const struct avc_thread_callback thread_cb = static const struct avc_thread_callback thread_cb =
{ {
...@@ -122,6 +123,18 @@ policy_reload_callback (u_int32_t event, security_id_t ssid, ...@@ -122,6 +123,18 @@ policy_reload_callback (u_int32_t event, security_id_t ssid,
return 0; return 0;
} }
/**
* Log any auxiliary data
*/
static void
log_audit_callback (void *data, security_class_t class, char *buf, size_t bufleft)
{
DBusString *audmsg = data;
_dbus_string_copy_to_buffer (audmsg, buf, bufleft);
_dbus_string_free (audmsg);
dbus_free (audmsg);
}
/** /**
* Create thread to notify the AVC of enforcing and policy reload * Create thread to notify the AVC of enforcing and policy reload
* changes via netlink. * changes via netlink.
...@@ -349,17 +362,28 @@ static dbus_bool_t ...@@ -349,17 +362,28 @@ static dbus_bool_t
bus_selinux_check (BusSELinuxID *sender_sid, bus_selinux_check (BusSELinuxID *sender_sid,
BusSELinuxID *override_sid, BusSELinuxID *override_sid,
security_class_t target_class, security_class_t target_class,
access_vector_t requested) access_vector_t requested,
unsigned long spid,
unsigned long tpid,
DBusString *auxdata)
{ {
if (!selinux_enabled) if (!selinux_enabled)
return TRUE; return TRUE;
if (auxdata)
{
if (spid && _dbus_string_append (auxdata, " spid="))
_dbus_string_append_uint (auxdata, spid);
if (tpid && _dbus_string_append (auxdata, " tpid="))
_dbus_string_append_uint (auxdata, tpid);
}
/* Make the security check. AVC checks enforcing mode here as well. */ /* Make the security check. AVC checks enforcing mode here as well. */
if (avc_has_perm (SELINUX_SID_FROM_BUS (sender_sid), if (avc_has_perm (SELINUX_SID_FROM_BUS (sender_sid),
override_sid ? override_sid ?
SELINUX_SID_FROM_BUS (override_sid) : SELINUX_SID_FROM_BUS (override_sid) :
SELINUX_SID_FROM_BUS (bus_sid), SELINUX_SID_FROM_BUS (bus_sid),
target_class, requested, &aeref, NULL) < 0) target_class, requested, &aeref, auxdata) < 0)
{ {
_dbus_verbose ("SELinux denying due to security policy.\n"); _dbus_verbose ("SELinux denying due to security policy.\n");
return FALSE; return FALSE;
...@@ -379,20 +403,40 @@ bus_selinux_check (BusSELinuxID *sender_sid, ...@@ -379,20 +403,40 @@ bus_selinux_check (BusSELinuxID *sender_sid,
*/ */
dbus_bool_t dbus_bool_t
bus_selinux_allows_acquire_service (DBusConnection *connection, bus_selinux_allows_acquire_service (DBusConnection *connection,
BusSELinuxID *service_sid) BusSELinuxID *service_sid,
const char *service_name)
{ {
#ifdef HAVE_SELINUX #ifdef HAVE_SELINUX
BusSELinuxID *connection_sid; BusSELinuxID *connection_sid;
unsigned long spid;
DBusString *auxdata;
if (!selinux_enabled) if (!selinux_enabled)
return TRUE; return TRUE;
connection_sid = bus_connection_get_selinux_id (connection); connection_sid = bus_connection_get_selinux_id (connection);
if (!dbus_connection_get_unix_process_id (connection, &spid))
spid = 0;
auxdata = dbus_new0 (DBusString, 1);
if (auxdata)
{
if (!_dbus_string_init (auxdata))
{
dbus_free (auxdata);
auxdata = NULL;
}
else if (_dbus_string_append (auxdata, "service="))
_dbus_string_append (auxdata, service_name);
}
return bus_selinux_check (connection_sid, return bus_selinux_check (connection_sid,
service_sid, service_sid,
SECCLASS_DBUS, SECCLASS_DBUS,
DBUS__ACQUIRE_SVC); DBUS__ACQUIRE_SVC,
spid,
0,
auxdata);
#else #else
return TRUE; return TRUE;
#endif /* HAVE_SELINUX */ #endif /* HAVE_SELINUX */
...@@ -410,15 +454,50 @@ bus_selinux_allows_acquire_service (DBusConnection *connection, ...@@ -410,15 +454,50 @@ bus_selinux_allows_acquire_service (DBusConnection *connection,
*/ */
dbus_bool_t dbus_bool_t
bus_selinux_allows_send (DBusConnection *sender, bus_selinux_allows_send (DBusConnection *sender,
DBusConnection *proposed_recipient) DBusConnection *proposed_recipient,
const char *msgtype,
const char *interface,
const char *member,
const char *error_name,
const char *destination)
{ {
#ifdef HAVE_SELINUX #ifdef HAVE_SELINUX
BusSELinuxID *recipient_sid; BusSELinuxID *recipient_sid;
BusSELinuxID *sender_sid; BusSELinuxID *sender_sid;
unsigned long spid, tpid;
DBusString *auxdata;
if (!selinux_enabled) if (!selinux_enabled)
return TRUE; return TRUE;
if (!dbus_connection_get_unix_process_id (sender, &spid))
spid = 0;
if (!dbus_connection_get_unix_process_id (proposed_recipient, &tpid))
tpid = 0;
auxdata = dbus_new0 (DBusString, 1);
if (auxdata)
{
if (!_dbus_string_init (auxdata))
{
dbus_free (auxdata);
auxdata = NULL;
}
else
{
if (_dbus_string_append (auxdata, "msgtype="))
_dbus_string_append (auxdata, msgtype);
if (interface && _dbus_string_append (auxdata, " interface="))
_dbus_string_append (auxdata, interface);
if (member && _dbus_string_append (auxdata, " member="))
_dbus_string_append (auxdata, member);
if (error_name && _dbus_string_append (auxdata, " error_name="))
_dbus_string_append (auxdata, error_name);
if (destination && _dbus_string_append (auxdata, " dest="))
_dbus_string_append (auxdata, destination);
}
}
sender_sid = bus_connection_get_selinux_id (sender); sender_sid = bus_connection_get_selinux_id (sender);
/* A NULL proposed_recipient means the bus itself. */ /* A NULL proposed_recipient means the bus itself. */
if (proposed_recipient) if (proposed_recipient)
...@@ -427,7 +506,8 @@ bus_selinux_allows_send (DBusConnection *sender, ...@@ -427,7 +506,8 @@ bus_selinux_allows_send (DBusConnection *sender,
recipient_sid = BUS_SID_FROM_SELINUX (bus_sid); recipient_sid = BUS_SID_FROM_SELINUX (bus_sid);
return bus_selinux_check (sender_sid, recipient_sid, return bus_selinux_check (sender_sid, recipient_sid,
SECCLASS_DBUS, DBUS__SEND_MSG); SECCLASS_DBUS, DBUS__SEND_MSG,
spid, tpid, auxdata);
#else #else
return TRUE; return TRUE;
#endif /* HAVE_SELINUX */ #endif /* HAVE_SELINUX */
......
...@@ -47,11 +47,15 @@ const char* bus_selinux_get_policy_root (void); ...@@ -47,11 +47,15 @@ const char* bus_selinux_get_policy_root (void);
dbus_bool_t bus_selinux_allows_acquire_service (DBusConnection *connection, dbus_bool_t bus_selinux_allows_acquire_service (DBusConnection *connection,
BusSELinuxID *service_sid); BusSELinuxID *service_sid,
const char *service_name);
dbus_bool_t bus_selinux_allows_send (DBusConnection *sender, dbus_bool_t bus_selinux_allows_send (DBusConnection *sender,
DBusConnection *proposed_recipient); DBusConnection *proposed_recipient,
const char *msgtype, /* Supplementary audit data */
const char *interface,
const char *member,
const char *error_name,
const char *destination);
BusSELinuxID* bus_selinux_init_connection_id (DBusConnection *connection, BusSELinuxID* bus_selinux_init_connection_id (DBusConnection *connection,
DBusError *error); DBusError *error);
......
...@@ -310,7 +310,8 @@ bus_registry_acquire_service (BusRegistry *registry, ...@@ -310,7 +310,8 @@ bus_registry_acquire_service (BusRegistry *registry,
sid = bus_selinux_id_table_lookup (registry->service_sid_table, sid = bus_selinux_id_table_lookup (registry->service_sid_table,
service_name); service_name);
if (!bus_selinux_allows_acquire_service (connection, sid)) if (!bus_selinux_allows_acquire_service (connection, sid,
_dbus_string_get_const_data (service_name)))
{ {
dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED, dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
"Connection \"%s\" is not allowed to own the service \"%s\" due " "Connection \"%s\" is not allowed to own the service \"%s\" due "
......
...@@ -5778,6 +5778,37 @@ dbus_message_type_from_string (const char *type_str) ...@@ -5778,6 +5778,37 @@ dbus_message_type_from_string (const char *type_str)
return DBUS_MESSAGE_TYPE_INVALID; return DBUS_MESSAGE_TYPE_INVALID;
} }
/**
* Utility function to convert a D-BUS message type into a
* machine-readable string (not translated).
*
* @code
* DBUS_MESSAGE_TYPE_METHOD_CALL -> "method_call"
* DBUS_MESSAGE_TYPE_METHOD_RETURN -> "method_return"
* DBUS_MESSAGE_TYPE_SIGNAL -> "signal"
* DBUS_MESSAGE_TYPE_ERROR -> "error"
* DBUS_MESSAGE_TYPE_INVALID -> "invalid"
* @endcode
*
*/
const char *
dbus_message_type_to_string (int type)
{
switch (type)
{
case DBUS_MESSAGE_TYPE_METHOD_CALL:
return "method_call";
case DBUS_MESSAGE_TYPE_METHOD_RETURN:
return "method_return";
case DBUS_MESSAGE_TYPE_SIGNAL:
return "signal";
case DBUS_MESSAGE_TYPE_ERROR:
return "error";
default:
return "invalid";
}
}
/** @} */ /** @} */
#ifdef DBUS_BUILD_TESTS #ifdef DBUS_BUILD_TESTS
#include "dbus-test.h" #include "dbus-test.h"
......
...@@ -295,6 +295,7 @@ void* dbus_message_get_data (DBusMessage *message, ...@@ -295,6 +295,7 @@ void* dbus_message_get_data (DBusMessage *message,
dbus_int32_t slot); dbus_int32_t slot);
int dbus_message_type_from_string (const char *type_str); int dbus_message_type_from_string (const char *type_str);
const char * dbus_message_type_to_string (int type);
DBUS_END_DECLS DBUS_END_DECLS
......
...@@ -756,6 +756,30 @@ _dbus_string_copy_data_len (const DBusString *str, ...@@ -756,6 +756,30 @@ _dbus_string_copy_data_len (const DBusString *str,
return TRUE; return TRUE;
} }
/**
* Copies the contents of a DBusString into a different
* buffer. The resulting buffer will be nul-terminated.
*
* @param str a string
* @param buffer a C buffer to copy data to
* @param len maximum length of C buffer
*/
void
_dbus_string_copy_to_buffer (const DBusString *str,
char *buffer,
int avail_len)
{
int copy_len;
DBUS_CONST_STRING_PREAMBLE (str);
_dbus_assert (avail_len >= 0);
copy_len = MIN (avail_len, real->len+1);
memcpy (buffer, real->str, copy_len);
if (avail_len > 0 && avail_len == copy_len)
buffer[avail_len-1] = '\0';
}
/** /**
* Gets the length of a string (not including nul termination). * Gets the length of a string (not including nul termination).
* *
......
...@@ -88,6 +88,9 @@ dbus_bool_t _dbus_string_copy_data_len (const DBusString *str, ...@@ -88,6 +88,9 @@ dbus_bool_t _dbus_string_copy_data_len (const DBusString *str,
char **data_return, char **data_return,
int start, int start,
int len); int len);
void _dbus_string_copy_to_buffer (const DBusString *str,
char *buffer,
int len);
int _dbus_string_get_length (const DBusString *str); int _dbus_string_get_length (const DBusString *str);
dbus_bool_t _dbus_string_lengthen (DBusString *str, dbus_bool_t _dbus_string_lengthen (DBusString *str,
int additional_length); int additional_length);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment