Пример #1
0
static void pid_query_result(DBusPendingCall *pend,
				void *user_data)
{
	char path[32];
	struct access_check *check = user_data;
	DBusMessage *reply = NULL;
	DBusMessageIter iter;
	dbus_uint32_t pid;
	struct stat st;
	guint name_watch;

	DBG("query for busname %s", check->busname);

	reply = dbus_pending_call_steal_reply(pend);
	if (!reply)
		goto done;

	if (!gid_hash)
		goto done;

	if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR)
		goto done;

	if (g_strcmp0(dbus_message_get_signature(reply), "u"))
		goto done;

	dbus_message_iter_init(reply, &iter);
	dbus_message_iter_get_basic(&iter, &pid);

	snprintf(path, sizeof(path), "/proc/%u", pid);
	if (stat(path, &st) < 0)
		goto done;

	DBG("query done, pid %d has gid %d", pid, st.st_gid);

	name_watch = g_dbus_add_disconnect_watch(check->connection, 
						check->busname,
						busname_exit_callback,
						g_strdup(check->busname),
						g_free);

	g_hash_table_replace(watch_hash, g_strdup(check->busname),
				GUINT_TO_POINTER(name_watch));
	g_hash_table_replace(gid_hash, g_strdup(check->busname),
				GINT_TO_POINTER(st.st_gid));

	if (gid_is_authorized(st.st_gid)) {
		DBG("allowing access for pid %d, pending %u",
			pid, check->pending);
		g_dbus_pending_success(check->connection, check->pending);
		check->pending_unanswered = FALSE;
	}

done:
	if (reply)
		dbus_message_unref(reply);
	dbus_pending_call_unref(pend);
}
Пример #2
0
static void builtin_security_result(dbus_bool_t authorized, void *user_data)
{
	struct builtin_security_data *data = user_data;

	if (authorized == TRUE)
		g_dbus_pending_success(data->conn, data->pending);
	else
		g_dbus_pending_error(data->conn, data->pending,
						DBUS_ERROR_AUTH_FAILED, NULL);

	g_free(data);
}
Пример #3
0
static void jolla_dbus_access_check(DBusConnection *connection,
					DBusMessage *message,
					const char *action,
					gboolean interaction,
					GDBusPendingReply pending)
{
	struct access_check *check = NULL;
	DBusMessage *query = NULL;
	DBusPendingCall *pend = NULL;
	const char *busname = dbus_message_get_sender(message);
	gpointer p;

	if (!busname)
		goto fail;

	if (!authorized_gids) {
		DBG("No authorization configuration, allowing busname '%s'",
			busname);
		g_dbus_pending_success(connection, pending);
		return;
	}

	if (g_hash_table_lookup_extended(gid_hash, busname, NULL, &p)) {
		gid_t gid = GPOINTER_TO_INT(p);
		DBG("known busname '%s' has gid %d", busname, gid);
		if (gid_is_authorized(gid)) {
			DBG("allowing access for known busname '%s', "
				"pending %u", busname, pending);
			g_dbus_pending_success(connection, pending);
			return;
		}

		goto fail;
	}

	query = dbus_message_new_method_call("org.freedesktop.DBus",
						"/",
						"org.freedesktop.DBus",
						"GetConnectionUnixProcessID");
	if (!query)
		goto fail;

	if (!dbus_message_append_args(query, DBUS_TYPE_STRING, &busname,
					DBUS_TYPE_INVALID))
		goto fail;

	if (!dbus_connection_send_with_reply(connection, query,	&pend, -1))
		goto fail;

	check = g_new0(struct access_check, 1);
	check->busname = g_strdup(busname);
	check->connection = dbus_connection_ref(connection);
	check->pending = pending;
	check->pending_unanswered = TRUE;

	if (!dbus_pending_call_set_notify(pend, pid_query_result,
						check, access_check_free))
		goto fail;

	DBG("pid query sent for pending %u", pending);

	return;

fail:
	if (check)
		access_check_free(check);

	if (pend) {
		dbus_pending_call_cancel(pend);
		dbus_pending_call_unref(pend);
	}

	if (query)
		dbus_message_unref(query);

	DBG("rejecting access for pending %u", pending);
	g_dbus_pending_error(connection, pending, DBUS_ERROR_AUTH_FAILED, NULL);
}