diff options
author | Konrad Lipinski <konrad.l@samsung.com> | 2017-01-18 16:44:34 +0100 |
---|---|---|
committer | Konrad Lipinski <konrad.l@samsung.com> | 2017-02-03 13:46:06 +0100 |
commit | fc278ebd7e5db244b659b0eea74b1c856f01f584 (patch) | |
tree | 03bd8d0be67f34179fdb2fb5ef50c28e1be687e3 | |
parent | 5754f7e51f77828789bdf062c800833fd7d5974f (diff) | |
download | dbus-sandbox/konradl/tizen.tar.gz dbus-sandbox/konradl/tizen.tar.bz2 dbus-sandbox/konradl/tizen.zip |
org.freedesktop.DBus.UpdateCredentials, dbus_bus_update_credentialssandbox/konradl/tizen
-rw-r--r-- | bus/driver.c | 22 | ||||
-rw-r--r-- | dbus/dbus-bus.c | 40 | ||||
-rw-r--r-- | dbus/dbus-bus.h | 3 | ||||
-rw-r--r-- | dbus/dbus-connection.c | 13 | ||||
-rw-r--r-- | dbus/dbus-connection.h | 2 | ||||
-rw-r--r-- | dbus/dbus-message.c | 2 | ||||
-rwxr-xr-x | dbus/dbus-transport-kdbus.c | 382 | ||||
-rw-r--r-- | dbus/kdbus.h | 3 |
8 files changed, 310 insertions, 157 deletions
diff --git a/bus/driver.c b/bus/driver.c index 16454316..720b7e88 100644 --- a/bus/driver.c +++ b/bus/driver.c @@ -1388,6 +1388,24 @@ bus_driver_handle_add_match (DBusConnection *connection, return BUS_RESULT_FALSE; } +static BusResult bus_driver_handle_update_credentials(DBusConnection *connection, + BusTransaction *transaction, + DBusMessage *message, + DBusError *error) +{ +#ifdef DBUS_ENABLE_SMACK + if (!dbus_connection_reset_smack_label(connection)) + { + dbus_set_error(error, DBUS_ERROR_FAILED, "Failed to get seclabel"); + return BUS_RESULT_FALSE; + } +#endif + + return send_ack_reply (connection, transaction, message, error) + ? BUS_RESULT_TRUE + : BUS_RESULT_FALSE; +} + static BusResult bus_driver_handle_remove_match (DBusConnection *connection, BusTransaction *transaction, @@ -2393,6 +2411,10 @@ static const MessageHandler dbus_message_handlers[] = { DBUS_TYPE_STRING_AS_STRING, DBUS_TYPE_STRING_AS_STRING, bus_smack_handle_get_connection_context }, + { "UpdateCredentials", + "", + "", + bus_driver_handle_update_credentials }, { NULL, NULL, NULL, NULL } }; diff --git a/dbus/dbus-bus.c b/dbus/dbus-bus.c index 6c66e1c9..81a47eac 100644 --- a/dbus/dbus-bus.c +++ b/dbus/dbus-bus.c @@ -1606,4 +1606,44 @@ dbus_bus_remove_match (DBusConnection *connection, dbus_message_unref (msg); } +/** + * Updates connection metadata (ex. creds, seclabel) to current values. + * + * @param connection the connection. + * @returns #TRUE iff successful + */ +dbus_bool_t +dbus_bus_update_credentials (DBusConnection *connection, DBusError *error) +{ + DBusMessage *msg; + DBusMessage *reply; + + _dbus_return_val_if_fail (connection != NULL, FALSE); + + msg = dbus_message_new_method_call (DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + "UpdateCredentials"); + + reply = dbus_connection_send_with_reply_and_block (connection, msg, + -1, error); + dbus_message_unref (msg); + + if (reply == NULL) + { + _DBUS_ASSERT_ERROR_IS_SET (error); + return FALSE; + } + + if (dbus_set_error_from_message (error, reply)) + { + _DBUS_ASSERT_ERROR_IS_SET (error); + dbus_message_unref (reply); + return FALSE; + } + + dbus_message_unref (reply); + return TRUE; +} + /** @} */ diff --git a/dbus/dbus-bus.h b/dbus/dbus-bus.h index 02a95711..1fcb2c9e 100644 --- a/dbus/dbus-bus.h +++ b/dbus/dbus-bus.h @@ -87,6 +87,9 @@ DBUS_EXPORT void dbus_bus_remove_match (DBusConnection *connection, const char *rule, DBusError *error); +DBUS_EXPORT +dbus_bool_t dbus_bus_update_credentials (DBusConnection *connection, + DBusError *error); /** @} */ diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c index 9a5be336..dc17a6a6 100644 --- a/dbus/dbus-connection.c +++ b/dbus/dbus-connection.c @@ -5439,6 +5439,19 @@ dbus_connection_get_smack_label (DBusConnection *connection, *label = connection->peer_smack_label; return *label != NULL; } + +dbus_bool_t +dbus_connection_reset_smack_label (DBusConnection *connection) +{ + unsigned long pid; + char *label; + if (!dbus_connection_get_unix_process_id (connection, &pid) + || 0 > smack_new_label_from_process (pid, &label)) + return FALSE; + free(connection->peer_smack_label); + connection->peer_smack_label = label; + return TRUE; +} #endif /** diff --git a/dbus/dbus-connection.h b/dbus/dbus-connection.h index aac57046..c0da37b4 100644 --- a/dbus/dbus-connection.h +++ b/dbus/dbus-connection.h @@ -268,6 +268,8 @@ dbus_bool_t dbus_connection_get_unix_process_id (DBusConnection DBUS_EXPORT dbus_bool_t dbus_connection_get_smack_label (DBusConnection *connection, const char **label); +DBUS_EXPORT +dbus_bool_t dbus_connection_reset_smack_label (DBusConnection *connection); #endif DBUS_EXPORT dbus_bool_t dbus_connection_get_adt_audit_session_data (DBusConnection *connection, diff --git a/dbus/dbus-message.c b/dbus/dbus-message.c index 0e3f323b..97707e65 100644 --- a/dbus/dbus-message.c +++ b/dbus/dbus-message.c @@ -4573,7 +4573,7 @@ _dbus_message_loader_queue_messages (DBusMessageLoader *loader) _dbus_assert (loader->messages != NULL); _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL); - } + } else { _dbus_verbose ("Initial peek at header says we don't have a whole message yet, or data broken with invalid code %d\n", diff --git a/dbus/dbus-transport-kdbus.c b/dbus/dbus-transport-kdbus.c index 893a3eff..a0647267 100755 --- a/dbus/dbus-transport-kdbus.c +++ b/dbus/dbus-transport-kdbus.c @@ -44,12 +44,14 @@ #include <string.h> #include <stdlib.h> #include <unistd.h> +#include <sys/ioctl.h> #include <sys/mman.h> #include <sys/stat.h> #include <sys/syscall.h> #include <fcntl.h> #ifdef LIBDBUSPOLICY #include <dbuspolicy/libdbuspolicy1.h> +#include <sys/smack.h> #include "dbus-marshal-header.h" #include "dbus-protocol-gvariant.h" #endif @@ -163,12 +165,15 @@ struct DBusTransportKdbus Matchmaker *matchmaker; /**< for match rules management */ dbus_uint32_t client_serial; /**< serial number for messages synthesized by library*/ #ifdef LIBDBUSPOLICY - void *policy; + uid_t uid; + gid_t gid; + bool dbuspolicy_bus_type; + char *label; #endif }; /** - * Creates unique name string frong unique id. + * Creates unique name string from unique id. * * @param id unique id * @returns allocated string with unique name @@ -651,27 +656,26 @@ static int can_send (DBusTransportKdbus *transport, DBusMessage *message) { + int ret = DBUSPOLICY_RESULT_ALLOW; + dbus_uint32_t reply_serial = dbus_message_get_reply_serial (message); - int ret = DBUSPOLICY_RESULT_ALLOW; - if (NULL != transport->policy) - { - dbus_uint32_t reply_serial = dbus_message_get_reply_serial (message); - - /* If reply_serial is non-zero, then it is a reply - just send it. - * Otherwise - check the policy. - */ - if (0 == reply_serial) - ret = dbuspolicy1_check_out (transport->policy, - dbus_message_get_destination (message), - dbus_message_get_sender (message), - dbus_message_get_path (message), - dbus_message_get_interface (message), - dbus_message_get_member (message), - dbus_message_get_type (message), - dbus_message_get_error_name (message), - reply_serial, - !dbus_message_get_no_reply (message)); - } + /* If reply_serial is non-zero, then it is a reply - just send it. + * Otherwise - check the policy. + */ + if (0 == reply_serial) + ret = dbuspolicy1_check_out (transport->dbuspolicy_bus_type, + transport->uid, + transport->gid, + transport->label, + dbus_message_get_destination (message), + dbus_message_get_sender (message), + dbus_message_get_path (message), + dbus_message_get_interface (message), + dbus_message_get_member (message), + dbus_message_get_type (message), + dbus_message_get_error_name (message), + reply_serial, + !dbus_message_get_no_reply (message)); return ret; } @@ -1222,8 +1226,7 @@ can_own (DBusTransportKdbus *transport, dbus_bool_t result = TRUE; #ifdef LIBDBUSPOLICY - if (NULL != transport->policy) - result = (dbuspolicy1_can_own (transport->policy, name) == 1); + result = (dbuspolicy1_can_own (transport->dbuspolicy_bus_type, transport->uid, transport->gid, transport->label, name) == DBUSPOLICY_RESULT_ALLOW); #endif return result; @@ -1666,6 +1669,12 @@ add_match_kdbus (DBusTransportKdbus *transport, return TRUE; } +static char *getlabel() { + char *l; + ssize_t r = smack_new_label_from_self(&l); + return r<0 ? NULL : l; +} + static DBusMessage * capture_org_freedesktop_DBus_Hello (DBusTransportKdbus *transport, DBusMessage *message, @@ -1681,6 +1690,13 @@ capture_org_freedesktop_DBus_Hello (DBusTransportKdbus *transport, if (!bus_register_kdbus (transport, registration_flags, error)) goto out; +#ifdef LIBDBUSPOLICY + transport->uid = getuid(); + transport->gid = getgid(); + if (!(transport->label = getlabel())) + goto out; +#endif + return reply_1_data (message, DBUS_TYPE_STRING, &transport->my_DBus_unique_name); out: @@ -2364,6 +2380,64 @@ struct CaptureHandlers { CaptureHandler handler; }; +static dbus_bool_t kdbus_update_credentials(DBusTransport *transport, DBusError *error) +{ + DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport; + int fd = _kdbus_get_fd(kdbus_transport->kdbus); + int ret; + char *label; + + if (!(label = getlabel())) + { + dbus_set_error(error, DBUS_ERROR_FAILED, "Failed to get seclabel"); + return FALSE; + } + + do + ret = ioctl(fd, KDBUS_CMD_UPDATE_METADATA); + while (ret<0 && EINTR == (ret = errno)); + if (ret<0) + { + dbus_set_error(error, _dbus_error_from_errno(ret), NULL); + free(label); + return FALSE; + } + + free(kdbus_transport->label); + kdbus_transport->label = label; + kdbus_transport->uid = getuid(); + kdbus_transport->gid = getgid(); + + return TRUE; +} + +static DBusMessage * +capture_org_freedesktop_DBus_UpdateCredentials (DBusTransportKdbus *transport, + DBusMessage *message, + DBusError *error) +{ + DBusMessage *reply; + if (dbus_message_has_signature (message, "")) + { + dbus_set_error(error, DBUS_ERROR_FAILED, "UpdateCredentials with nonempty signature"); + return NULL; + } + + + if (!kdbus_update_credentials ((DBusTransport*)transport, error)) + return NULL; + + if ((reply = dbus_message_new_method_return (message))) + if (!dbus_message_set_sender (reply, DBUS_SERVICE_DBUS)) + { + dbus_message_unref(reply); + reply = NULL; + } + if (!reply) + dbus_set_error(error, _dbus_error_from_errno(ENOMEM), NULL); + return reply; +} + #define HANDLER_ELEMENT(x) {#x, capture_org_freedesktop_DBus_##x} /* This is to cut the code to parts, and keep it organized: @@ -2391,7 +2465,8 @@ static struct CaptureHandlers capture_handlers[] = HANDLER_ELEMENT (NameHasOwner), HANDLER_ELEMENT (ReloadConfig), HANDLER_ELEMENT (StartServiceByName), - HANDLER_ELEMENT (UpdateActivationEnvironment) + HANDLER_ELEMENT (UpdateActivationEnvironment), + HANDLER_ELEMENT (UpdateCredentials) }; /** @@ -2804,132 +2879,132 @@ can_receive (DBusTransportKdbus *transport, dbus_bool_t result = TRUE; #ifdef LIBDBUSPOLICY - if (transport->policy) - { - DBusHeader header; - dbus_bool_t got_header = FALSE; - dbus_bool_t got_creds = FALSE; - dbus_bool_t got_seclabel = FALSE; + DBusHeader header; + dbus_bool_t got_header = FALSE; + dbus_bool_t got_creds = FALSE; + dbus_bool_t got_seclabel = FALSE; - if (KDBUS_PAYLOAD_DBUS == msg->payload_type) - { - const struct kdbus_item *item; - uid_t sender_euid = -1; - gid_t sender_egid = -1; - const char *seclabel = NULL; - DBusString names; + if (KDBUS_PAYLOAD_DBUS == msg->payload_type) + { + const struct kdbus_item *item; + uid_t sender_euid = -1; + gid_t sender_egid = -1; + const char *seclabel = NULL; + DBusString names; - result = FALSE; + result = FALSE; - _dbus_string_init (&names); + _dbus_string_init (&names); - KDBUS_ITEM_FOREACH(item, msg, items) - switch (item->type) - { - case KDBUS_ITEM_CREDS: - sender_euid = (uid_t) item->creds.euid; - sender_egid = (gid_t) item->creds.egid; - got_creds = (sender_euid != (uid_t)-1) && (sender_egid != (gid_t)-1); - break; - case KDBUS_ITEM_SECLABEL: - seclabel = item->str; - got_seclabel = (seclabel != NULL); - break; - case KDBUS_ITEM_OWNED_NAME: - { - DBusString name; - _dbus_string_init_const (&name, item->name.name); - if (_dbus_validate_bus_name (&name, 0, _dbus_string_get_length (&name))) - { - if (_dbus_string_get_length (&names) != 0) - _dbus_string_append_byte (&names, ' '); - - _dbus_string_copy (&name, - 0, - &names, - _dbus_string_get_length (&names)); - } - } - break; - default: - break; /* ignore all other items */ - } - - if (NULL != message_data && message_len > 0) + KDBUS_ITEM_FOREACH(item, msg, items) + switch (item->type) { - if (load_dbus_header (transport, &header, message_data, message_len)) - got_header = TRUE; + case KDBUS_ITEM_CREDS: + sender_euid = (uid_t) item->creds.euid; + sender_egid = (gid_t) item->creds.egid; + got_creds = (sender_euid != (uid_t)-1) && (sender_egid != (gid_t)-1); + break; + case KDBUS_ITEM_SECLABEL: + seclabel = item->str; + got_seclabel = (seclabel != NULL); + break; + case KDBUS_ITEM_OWNED_NAME: + { + DBusString name; + _dbus_string_init_const (&name, item->name.name); + if (_dbus_validate_bus_name (&name, 0, _dbus_string_get_length (&name))) + { + if (_dbus_string_get_length (&names) != 0) + _dbus_string_append_byte (&names, ' '); + + _dbus_string_copy (&name, + 0, + &names, + _dbus_string_get_length (&names)); + } + } + break; + default: + break; /* ignore all other items */ } - if (got_header && _dbus_header_get_message_type (&header) != DBUS_MESSAGE_TYPE_METHOD_CALL) - { - result = TRUE; - } - else if (got_header && got_creds && got_seclabel) - { - const char *destination = NULL; - const char *path = NULL; - const char *interface = NULL; - const char *member = NULL; - const char *error_name = NULL; - dbus_uint64_t reply_cookie = 0; - dbus_bool_t requested_reply = FALSE; - int ret; - - _dbus_header_get_field_basic (&header, - DBUS_HEADER_FIELD_DESTINATION, - DBUS_TYPE_STRING, - &destination); - - _dbus_header_get_field_basic (&header, - DBUS_HEADER_FIELD_PATH, - DBUS_TYPE_STRING, - &path); - - _dbus_header_get_field_basic (&header, - DBUS_HEADER_FIELD_INTERFACE, - DBUS_TYPE_STRING, - &interface); - - _dbus_header_get_field_basic (&header, - DBUS_HEADER_FIELD_MEMBER, - DBUS_TYPE_STRING, - &member); - - _dbus_header_get_field_basic (&header, - DBUS_HEADER_FIELD_ERROR_NAME, - DBUS_TYPE_STRING, - &error_name); - - _dbus_header_get_field_basic (&header, - DBUS_HEADER_FIELD_REPLY_SERIAL, - DBUS_TYPE_UINT64, - &reply_cookie); - - requested_reply = !(_dbus_header_get_flag (&header, - DBUS_HEADER_FLAG_NO_REPLY_EXPECTED)); - - ret = dbuspolicy1_check_in (transport->policy, - destination, - _dbus_string_get_length (&names) > 0 ? - _dbus_string_get_const_data (&names) : - NULL, - seclabel, - sender_euid, - sender_egid, - path, - interface, - member, - _dbus_header_get_message_type (&header), - error_name, - reply_cookie, - requested_reply); - result = (1 == ret); - } + if (NULL != message_data && message_len > 0) + { + if (load_dbus_header (transport, &header, message_data, message_len)) + got_header = TRUE; + } - _dbus_string_free (&names); - } - } + if (got_header && _dbus_header_get_message_type (&header) != DBUS_MESSAGE_TYPE_METHOD_CALL) + { + result = TRUE; + } + else if (got_header && got_creds && got_seclabel) + { + const char *destination = NULL; + const char *path = NULL; + const char *interface = NULL; + const char *member = NULL; + const char *error_name = NULL; + dbus_uint64_t reply_cookie = 0; + dbus_bool_t requested_reply = FALSE; + int ret; + + _dbus_header_get_field_basic (&header, + DBUS_HEADER_FIELD_DESTINATION, + DBUS_TYPE_STRING, + &destination); + + _dbus_header_get_field_basic (&header, + DBUS_HEADER_FIELD_PATH, + DBUS_TYPE_STRING, + &path); + + _dbus_header_get_field_basic (&header, + DBUS_HEADER_FIELD_INTERFACE, + DBUS_TYPE_STRING, + &interface); + + _dbus_header_get_field_basic (&header, + DBUS_HEADER_FIELD_MEMBER, + DBUS_TYPE_STRING, + &member); + + _dbus_header_get_field_basic (&header, + DBUS_HEADER_FIELD_ERROR_NAME, + DBUS_TYPE_STRING, + &error_name); + + _dbus_header_get_field_basic (&header, + DBUS_HEADER_FIELD_REPLY_SERIAL, + DBUS_TYPE_UINT64, + &reply_cookie); + + requested_reply = !(_dbus_header_get_flag (&header, + DBUS_HEADER_FLAG_NO_REPLY_EXPECTED)); + + ret = dbuspolicy1_check_in (transport->dbuspolicy_bus_type, + transport->uid, + transport->gid, + transport->label, + destination, + _dbus_string_get_length (&names) > 0 ? + _dbus_string_get_const_data (&names) : + NULL, + seclabel, + sender_euid, + sender_egid, + path, + interface, + member, + _dbus_header_get_message_type (&header), + error_name, + reply_cookie, + requested_reply); + result = (DBUSPOLICY_RESULT_ALLOW == ret); + } + + _dbus_string_free (&names); + } #endif return result; @@ -3439,15 +3514,6 @@ free_watches (DBusTransportKdbus *kdbus_transport) _dbus_verbose ("end\n"); } -static void -free_policies (DBusTransportKdbus *transport) -{ -#ifdef LIBDBUSPOLICY - if (NULL != transport->policy) - dbuspolicy1_free (transport->policy); -#endif -} - /** * Copy-paste from socket transport. Only done needed renames and removed * lines related to encoded messages. @@ -3469,11 +3535,13 @@ transport_finalize (DBusTransport *transport) dbus_free (kdbus_transport->activator); - free_policies ( kdbus_transport ); - _kdbus_free (kdbus_transport->kdbus); free (kdbus_transport->my_DBus_unique_name); +#ifdef LIBDBUSPOLICY + free (kdbus_transport->label); +#endif + dbus_free (transport); } @@ -4247,9 +4315,11 @@ initialize_policies (DBusTransportKdbus *transport, const char *path) dbus_bool_t result = TRUE; #ifdef LIBDBUSPOLICY - transport->policy = dbuspolicy1_init (path); - if (NULL == transport->policy) + int bus_type = dbuspolicy1_init (path); + if (0 > bus_type) result = FALSE; + else + transport->dbuspolicy_bus_type = bus_type; #endif return result; diff --git a/dbus/kdbus.h b/dbus/kdbus.h index 4fc44cb1..778bccb2 100644 --- a/dbus/kdbus.h +++ b/dbus/kdbus.h @@ -979,6 +979,9 @@ enum kdbus_ioctl_type { struct kdbus_cmd_match), KDBUS_CMD_MATCH_REMOVE = _IOW(KDBUS_IOCTL_MAGIC, 0xb1, struct kdbus_cmd_match), + + /* Tizen */ + KDBUS_CMD_UPDATE_METADATA = _IO(KDBUS_IOCTL_MAGIC, 0xd0), }; #endif /* _UAPI_KDBUS_H_ */ |