*
*/
+#include <dbus/dbus-connection-internal.h>
#include "kdbus-d.h"
#include <dbus/kdbus.h>
-#include <dbus/dbus-connection-internal.h>
#include <dbus/dbus-bus.h>
#include "dispatch.h"
#include <dbus/kdbus-common.h>
#include <dbus/dbus-transport.h>
#include <dbus/dbus-transport-kdbus.h>
+#include "connection.h"
#include <utils.h>
#include <stdlib.h>
return ret;
}
+
+DBusConnection* create_phantom_connection(DBusConnection* connection, const char* unique_name)
+{
+ DBusConnection *phantom_connection;
+ DBusString name;
+ DBusError error;
+
+ _dbus_string_init_const(&name, unique_name);
+
+ phantom_connection = _dbus_connection_new_for_used_transport (dbus_connection_get_transport(connection));
+ if(phantom_connection == NULL)
+ return FALSE;
+ if(!bus_connections_setup_connection(bus_connection_get_connections(connection), phantom_connection))
+ {
+ /*todo FIXME something should be done to clean up the phantom connection
+ * but we can't use standard disconnect, unref or last_unref because the transport is taken from connection
+ * so we probably should write own function on the basis of _dbus_connection_last_unref
+ */
+ phantom_connection = NULL;
+ }
+ if(!bus_connection_complete(phantom_connection, &name, &error))
+ {
+ /* todo FIXME exactly the same issue as above */
+ phantom_connection = NULL;
+ }
+
+ _dbus_verbose ("Created phantom connection for %s\n", bus_connection_get_name(phantom_connection));
+
+ return phantom_connection;
+}
*
* @param transport the transport.
* @returns the new connection, or #NULL on failure.
- */
-DBusConnection*
-_dbus_connection_new_for_transport (DBusTransport *transport)
+*/
+static DBusConnection*
+_dbus_connection_new_for_transport_internal (DBusTransport *transport, dbus_bool_t exists)
{
DBusConnection *connection;
DBusWatchList *watch_list;
pending_replies =
_dbus_hash_table_new (DBUS_HASH_INT,
- NULL,
+ NULL,
(DBusFreeFunction)free_pending_call_on_hash_removal);
if (pending_replies == NULL)
goto error;
connection->disconnect_message_link = disconnect_link;
- CONNECTION_LOCK (connection);
-
- if (!_dbus_transport_set_connection (transport, connection))
- {
- CONNECTION_UNLOCK (connection);
+ if(!exists)
+ {
+ CONNECTION_LOCK (connection);
- goto error;
- }
+ if (!_dbus_transport_set_connection (transport, connection))
+ {
+ CONNECTION_UNLOCK (connection);
- _dbus_transport_ref (transport);
+ goto error;
+ }
- CONNECTION_UNLOCK (connection);
+ _dbus_transport_ref (transport);
+
+ CONNECTION_UNLOCK (connection);
+ }
_dbus_connection_trace_ref (connection, 0, 1, "new_for_transport");
return connection;
}
/**
+ * Creates a new connection for the given transport. A transport
+ * represents a message stream that uses some concrete mechanism, such
+ * as UNIX domain sockets. May return #NULL if insufficient
+ * memory exists to create the connection.
+ *
+ * @param transport the transport.
+ * @returns the new connection, or #NULL on failure.
+ */
+DBusConnection*
+_dbus_connection_new_for_transport (DBusTransport *transport)
+{
+ return _dbus_connection_new_for_transport_internal(transport, FALSE);
+}
+
+DBusConnection*
+_dbus_connection_new_for_used_transport (DBusTransport *transport)
+{
+ return _dbus_connection_new_for_transport_internal(transport, TRUE);
+}
+
+/**
* Increments the reference count of a DBusConnection.
* Requires that the caller already holds the connection lock.
*
#define MEMFD_SIZE_THRESHOLD (2 * 1024 * 1024LU) // over this memfd is used
#define KDBUS_MSG_DECODE_DEBUG 0
+//#define DBUS_AUTHENTICATION
#define ITER_APPEND_STR(string) \
if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &string)) \
item = KDBUS_PART_NEXT(item);
item->type = KDBUS_MSG_DST_NAME;
item->size = KDBUS_PART_HEADER_SIZE + strlen(name) + 1;
- strcpy(item->str, name);
+ memcpy(item->str, name, item->size - KDBUS_PART_HEADER_SIZE);
}
else if (dst_id == KDBUS_DST_ID_BROADCAST)
{
item = msg->items;
item->type = KDBUS_NAME_INFO_ITEM_NAME;
item->size = item_size;
- strcpy(item->str, name);
+ memcpy(item->str, name, strlen(name) + 1);
again:
ret = ioctl(((DBusTransportSocket*)transport)->fd, KDBUS_CMD_NAME_QUERY, msg);
pInfo->uniqueId = msg->id;
pInfo->userId = msg->creds.uid;
pInfo->processId = msg->creds.pid;
-
item = msg->items;
while((uint8_t *)(item) < (uint8_t *)(msg) + msg->size)
{
if(item->type == KDBUS_NAME_INFO_ITEM_SECLABEL)
{
- pInfo->sec_label_len = item->size - KDBUS_PART_HEADER_SIZE - 1;
+ pInfo->sec_label_len = item->size - KDBUS_PART_HEADER_SIZE - 1;
if(pInfo->sec_label_len != 0)
{
pInfo->sec_label = malloc(pInfo->sec_label_len);
else
memcpy(pInfo->sec_label, item->data, pInfo->sec_label_len);
}
-
break;
}
item = KDBUS_PART_NEXT(item);
{
pItem->type = KDBUS_MATCH_SRC_NAME;
pItem->size = KDBUS_PART_HEADER_SIZE + name_size + 1;
- strcpy(pItem->str, pName);
+ memcpy(pItem->str, pName, strlen(pName) + 1);
pItem = KDBUS_PART_NEXT(pItem);
}
return ret_value;
}
#endif
- else if(!strcmp(dbus_message_get_member(message), "GetAdtAuditSessionData")) //todo to be implemented - now can not be simply passed to daemon
+/* else if(!strcmp(dbus_message_get_member(message), "GetAdtAuditSessionData")) //todo to be implemented
{
char* name = NULL;
dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID);
return reply_with_error(DBUS_ERROR_ADT_AUDIT_DATA_UNKNOWN, "Could not determine audit session data for '%s'", name, message, transport->connection);
- }
+ }*/
#ifdef DBUS_SERVICES_IN_LIB
else if(!strcmp(dbus_message_get_member(message), "GetConnectionSELinuxSecurityContext"))
{
_dbus_transport_ref (transport);
#ifdef DBUS_AUTHENTICATION
- if (_dbus_transport_get_is_authenticated (transport))
+ if (_dbus_transport_try_to_authenticate (transport))
#endif
needed = _dbus_connection_has_messages_to_send_unlocked (transport->connection);
#ifdef DBUS_AUTHENTICATION
_dbus_transport_ref (transport);
#ifdef DBUS_AUTHENTICATION
- if (_dbus_transport_get_is_authenticated (transport))
+ if (_dbus_transport_try_to_authenticate (transport))
#endif
need_read_watch =
(_dbus_counter_get_size_value (transport->live_messages) < transport->max_live_messages_size) &&
DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
DBusString *buffer;
int bytes_read;
+ int *fds, n_fds;
*oom = FALSE;
_dbus_auth_get_buffer (transport->auth, &buffer);
- bytes_read = kdbus_read_message(socket_transport, buffer);
+ bytes_read = kdbus_read_message(socket_transport, buffer, fds, &n_fds);
_dbus_auth_return_buffer (transport->auth, buffer,
bytes_read > 0 ? bytes_read : 0);
}
}
+static int kdbus_send_auth (DBusTransport *transport, const DBusString *buffer)
+{
+ int len;
+ int bytes_written = -1;
+ struct kdbus_msg *msg;
+ struct kdbus_item *item;
+
+ len = _dbus_string_get_length (buffer);
+// data = _dbus_string_get_const_data_len (buffer, 0, len);
+
+ msg = kdbus_init_msg(NULL, 1, 0, FALSE, 0, (DBusTransportSocket*)transport);
+ item = msg->items;
+ MSG_ITEM_BUILD_VEC(_dbus_string_get_const_data_len (buffer, 0, len), len);
+
+ again:
+ if(ioctl(((DBusTransportSocket*)transport)->fd, KDBUS_CMD_MSG_SEND, msg))
+ {
+ if(errno == EINTR)
+ goto again;
+ _dbus_verbose ("Error writing auth: %d, %m\n", errno);
+ }
+ else
+ bytes_written = len;
+
+ return bytes_written;
+}
+
/* Return value is whether we successfully wrote any bytes */
static dbus_bool_t
write_data_from_auth (DBusTransport *transport)
{
- DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
+// DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
int bytes_written;
const DBusString *buffer;
&buffer))
return FALSE;
- bytes_written = _dbus_write_socket (socket_transport->fd,
- buffer,
- 0, _dbus_string_get_length (buffer));
+ bytes_written = kdbus_send_auth (transport, buffer);
if (bytes_written > 0)
{
oom = FALSE;
- orig_auth_state = _dbus_transport_get_is_authenticated (transport);
+ orig_auth_state = _dbus_transport_try_to_authenticate (transport);
/* This is essential to avoid the check_write_watch() at the end,
* we don't want to add a write watch in do_iteration before
_dbus_transport_ref (transport);
- while (!_dbus_transport_get_is_authenticated (transport) &&
+ while (!_dbus_transport_try_to_authenticate (transport) &&
_dbus_transport_get_is_connected (transport))
{
if (!exchange_credentials (transport, do_reading, do_writing))
out:
if (auth_completed)
- *auth_completed = (orig_auth_state != _dbus_transport_get_is_authenticated (transport));
+ *auth_completed = (orig_auth_state != _dbus_transport_try_to_authenticate (transport));
check_read_watch (transport);
check_write_watch (transport);
#ifdef DBUS_AUTHENTICATION
/* No messages without authentication! */
- if (!_dbus_transport_get_is_authenticated (transport))
+ if (!_dbus_transport_try_to_authenticate (transport))
{
_dbus_verbose ("Not authenticated, not writing anything\n");
return TRUE;
#ifdef DBUS_AUTHENTICATION
/* No messages without authentication! */
- if (!_dbus_transport_get_is_authenticated (transport))
+ if (!_dbus_transport_try_to_authenticate (transport))
return TRUE;
#endif
poll_fd.fd = socket_transport->fd;
poll_fd.events = 0;
- if (_dbus_transport_peek_is_authenticated (transport))
+ if (_dbus_transport_try_to_authenticate (transport))
{
/* This is kind of a hack; if we have stuff to write, then try
* to avoid the poll. This is probably about a 5% speedup on an