libsysprof-ui: allow restricting remote proxy

This commit is contained in:
Christian Hergert
2019-05-19 22:36:20 -07:00
parent 6e7ef3d52d
commit c368da09de
9 changed files with 196 additions and 158 deletions

View File

@ -404,3 +404,148 @@ helpers_list_processes_finish (GAsyncResult *result,
return FALSE;
}
static gboolean
needs_escape (const gchar *str)
{
for (; *str; str++)
{
if (g_ascii_isspace (*str) || *str == '\'' || *str == '"')
return TRUE;
}
return FALSE;
}
static void
postprocess_cmdline (gchar **str,
gsize len)
{
g_autoptr(GPtrArray) parts = g_ptr_array_new_with_free_func (g_free);
g_autofree gchar *instr = NULL;
const gchar *begin = NULL;
if (len == 0)
return;
instr = *str;
for (gsize i = 0; i < len; i++)
{
if (!begin && instr[i])
{
begin = &instr[i];
}
else if (begin && instr[i] == '\0')
{
if (needs_escape (begin))
g_ptr_array_add (parts, g_shell_quote (begin));
else
g_ptr_array_add (parts, g_strdup (begin));
begin = NULL;
}
}
/* If the last byte was not \0, as can happen with prctl(), then we need
* to add it here manually.
*/
if (begin)
{
if (needs_escape (begin))
g_ptr_array_add (parts, g_shell_quote (begin));
else
g_ptr_array_add (parts, g_strdup (begin));
}
g_ptr_array_add (parts, NULL);
*str = g_strjoinv (" ", (gchar **)parts->pdata);
}
static void
postprocess_rstrip (gchar **str,
gsize len)
{
g_strchomp (*str);
}
static void
add_pid_proc_file_to (gint pid,
const gchar *name,
GVariantDict *dict,
void (*postprocess) (gchar **, gsize))
{
g_autofree gchar *path = NULL;
g_autofree gchar *contents = NULL;
gsize len;
g_assert (pid > -1);
g_assert (name != NULL);
g_assert (dict != NULL);
path = g_strdup_printf ("/proc/%d/%s", pid, name);
if (g_file_get_contents (path, &contents, &len, NULL))
{
if (postprocess)
postprocess (&contents, len);
g_variant_dict_insert (dict, name, "s", contents);
}
}
GVariant *
helpers_get_process_info (const gchar *attributes)
{
GVariantBuilder builder;
g_autofree gint *processes = NULL;
gsize n_processes = 0;
gboolean want_statm;
gboolean want_cmdline;
gboolean want_comm;
gboolean want_maps;
gboolean want_mountinfo;
if (attributes == NULL)
attributes = "";
want_statm = !!strstr (attributes, "statm");
want_cmdline = !!strstr (attributes, "cmdline");
want_maps = !!strstr (attributes, "maps");
want_mountinfo = !!strstr (attributes, "mountinfo");
want_comm = !!strstr (attributes, "comm");
g_variant_builder_init (&builder, G_VARIANT_TYPE ("aa{sv}"));
if (helpers_list_processes (&processes, &n_processes))
{
for (guint i = 0; i < n_processes; i++)
{
gint pid = processes[i];
GVariantDict dict;
g_variant_dict_init (&dict, NULL);
g_variant_dict_insert (&dict, "pid", "i", pid, NULL);
if (want_statm)
add_pid_proc_file_to (pid, "statm", &dict, postprocess_rstrip);
if (want_cmdline)
add_pid_proc_file_to (pid, "cmdline", &dict, postprocess_cmdline);
if (want_comm)
add_pid_proc_file_to (pid, "comm", &dict, postprocess_rstrip);
if (want_maps)
add_pid_proc_file_to (pid, "maps", &dict, postprocess_rstrip);
if (want_mountinfo)
add_pid_proc_file_to (pid, "mountinfo", &dict, postprocess_rstrip);
g_variant_builder_add_value (&builder, g_variant_dict_end (&dict));
}
}
return g_variant_take_ref (g_variant_builder_end (&builder));
}

View File

@ -27,26 +27,27 @@
G_BEGIN_DECLS
gboolean helpers_can_see_pids (void);
gboolean helpers_list_processes (gint32 **processes,
gsize *n_processes);
void helpers_list_processes_async (GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean helpers_list_processes_finish (GAsyncResult *result,
gint32 **processes,
gsize *n_processes,
GError **error);
gboolean helpers_perf_event_open (GVariant *options,
gint32 pid,
gint32 cpu,
gint group_fd,
guint64 flags,
gint *out_fd);
gboolean helpers_get_proc_file (const gchar *path,
gchar **contents,
gsize *len);
gboolean helpers_get_proc_fd (const gchar *path,
gint *out_fd);
gboolean helpers_can_see_pids (void);
gboolean helpers_list_processes (gint32 **processes,
gsize *n_processes);
void helpers_list_processes_async (GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean helpers_list_processes_finish (GAsyncResult *result,
gint32 **processes,
gsize *n_processes,
GError **error);
gboolean helpers_perf_event_open (GVariant *options,
gint32 pid,
gint32 cpu,
gint group_fd,
guint64 flags,
gint *out_fd);
gboolean helpers_get_proc_file (const gchar *path,
gchar **contents,
gsize *len);
gboolean helpers_get_proc_fd (const gchar *path,
gint *out_fd);
GVariant *helpers_get_process_info (const gchar *attributes);
G_END_DECLS

View File

@ -627,6 +627,7 @@ sysprof_helpers_authorize_finish (SysprofHelpers *self,
gboolean
sysprof_helpers_get_process_info (SysprofHelpers *self,
const gchar *attributes,
gboolean no_proxy,
GCancellable *cancellable,
GVariant **info,
GError **error)
@ -636,6 +637,12 @@ sysprof_helpers_get_process_info (SysprofHelpers *self,
g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
g_assert (info != NULL);
if (no_proxy)
{
*info = helpers_get_process_info (attributes);
return TRUE;
}
return ipc_service_call_get_process_info_sync (self->proxy, attributes, info, cancellable, error);
}

View File

@ -75,6 +75,7 @@ gboolean sysprof_helpers_get_proc_file_finish (SysprofHelpers
GError **error);
gboolean sysprof_helpers_get_process_info (SysprofHelpers *self,
const gchar *attributes,
gboolean no_proxy,
GCancellable *cancellable,
GVariant **info,
GError **error);

View File

@ -32,8 +32,9 @@
struct _SysprofProcessModel
{
GObject parent_instance;
guint reload_source;
GPtrArray *items;
guint reload_source;
guint no_proxy : 1;
};
static void list_model_iface_init (GListModelInterface *iface);
@ -181,6 +182,7 @@ sysprof_process_model_reload_worker (GTask *task,
gpointer task_data,
GCancellable *cancellable)
{
SysprofProcessModel *self = source_object;
SysprofHelpers *helpers = sysprof_helpers_get_default ();
g_autoptr(GPtrArray) ret = NULL;
g_autoptr(GVariant) info = NULL;
@ -190,7 +192,7 @@ sysprof_process_model_reload_worker (GTask *task,
ret = g_ptr_array_new_with_free_func (g_object_unref);
if (sysprof_helpers_get_process_info (helpers, "pid,cmdline,comm", NULL, &info, NULL))
if (sysprof_helpers_get_process_info (helpers, "pid,cmdline,comm", self->no_proxy, NULL, &info, NULL))
{
gsize n_children = g_variant_n_children (info);
@ -294,3 +296,12 @@ list_model_iface_init (GListModelInterface *iface)
iface->get_n_items = sysprof_process_model_get_n_items;
iface->get_item = sysprof_process_model_get_item;
}
void
sysprof_process_model_set_no_proxy (SysprofProcessModel *self,
gboolean no_proxy)
{
g_return_if_fail (SYSPROF_IS_PROCESS_MODEL (self));
self->no_proxy = !!no_proxy;
}

View File

@ -38,6 +38,9 @@ G_DECLARE_FINAL_TYPE (SysprofProcessModel, sysprof_process_model, SYSPROF, PROCE
SYSPROF_AVAILABLE_IN_ALL
SysprofProcessModel *sysprof_process_model_new (void);
SYSPROF_AVAILABLE_IN_ALL
void sysprof_process_model_set_no_proxy (SysprofProcessModel *self,
gboolean no_proxy);
SYSPROF_AVAILABLE_IN_ALL
void sysprof_process_model_reload (SysprofProcessModel *self);
SYSPROF_AVAILABLE_IN_ALL
void sysprof_process_model_queue_reload (SysprofProcessModel *self);

View File

@ -237,151 +237,19 @@ ipc_service_impl_g_authorize_method (GDBusInterfaceSkeleton *skeleton,
return ret;
}
static gboolean
needs_escape (const gchar *str)
{
for (; *str; str++)
{
if (g_ascii_isspace (*str) || *str == '\'' || *str == '"')
return TRUE;
}
return FALSE;
}
static void
postprocess_cmdline (gchar **str,
gsize len)
{
g_autoptr(GPtrArray) parts = g_ptr_array_new_with_free_func (g_free);
g_autofree gchar *instr = NULL;
const gchar *begin = NULL;
if (len == 0)
return;
instr = *str;
for (gsize i = 0; i < len; i++)
{
if (!begin && instr[i])
{
begin = &instr[i];
}
else if (begin && instr[i] == '\0')
{
if (needs_escape (begin))
g_ptr_array_add (parts, g_shell_quote (begin));
else
g_ptr_array_add (parts, g_strdup (begin));
begin = NULL;
}
}
/* If the last byte was not \0, as can happen with prctl(), then we need
* to add it here manually.
*/
if (begin)
{
if (needs_escape (begin))
g_ptr_array_add (parts, g_shell_quote (begin));
else
g_ptr_array_add (parts, g_strdup (begin));
}
g_ptr_array_add (parts, NULL);
*str = g_strjoinv (" ", (gchar **)parts->pdata);
}
static void
postprocess_rstrip (gchar **str,
gsize len)
{
g_strchomp (*str);
}
static void
add_pid_proc_file_to (gint pid,
const gchar *name,
GVariantDict *dict,
void (*postprocess) (gchar **, gsize))
{
g_autofree gchar *path = NULL;
g_autofree gchar *contents = NULL;
gsize len;
g_assert (pid > -1);
g_assert (name != NULL);
g_assert (dict != NULL);
path = g_strdup_printf ("/proc/%d/%s", pid, name);
if (g_file_get_contents (path, &contents, &len, NULL))
{
if (postprocess)
postprocess (&contents, len);
g_variant_dict_insert (dict, name, "s", contents);
}
}
static gboolean
ipc_service_impl_handle_get_process_info (IpcService *service,
GDBusMethodInvocation *invocation,
const gchar *attributes)
{
GVariantBuilder builder;
g_autofree gint *processes = NULL;
gsize n_processes = 0;
gboolean want_statm;
gboolean want_cmdline;
gboolean want_comm;
gboolean want_maps;
gboolean want_mountinfo;
g_autoptr(GVariant) res = NULL;
g_assert (IPC_IS_SERVICE (service));
g_assert (G_IS_DBUS_METHOD_INVOCATION (invocation));
g_assert (attributes != NULL);
want_statm = !!strstr (attributes, "statm");
want_cmdline = !!strstr (attributes, "cmdline");
want_maps = !!strstr (attributes, "maps");
want_mountinfo = !!strstr (attributes, "mountinfo");
want_comm = !!strstr (attributes, "comm");
g_variant_builder_init (&builder, G_VARIANT_TYPE ("aa{sv}"));
if (helpers_list_processes (&processes, &n_processes))
{
for (guint i = 0; i < n_processes; i++)
{
gint pid = processes[i];
GVariantDict dict;
g_variant_dict_init (&dict, NULL);
g_variant_dict_insert (&dict, "pid", "i", pid, NULL);
if (want_statm)
add_pid_proc_file_to (pid, "statm", &dict, postprocess_rstrip);
if (want_cmdline)
add_pid_proc_file_to (pid, "cmdline", &dict, postprocess_cmdline);
if (want_comm)
add_pid_proc_file_to (pid, "comm", &dict, postprocess_rstrip);
if (want_maps)
add_pid_proc_file_to (pid, "maps", &dict, postprocess_rstrip);
if (want_mountinfo)
add_pid_proc_file_to (pid, "mountinfo", &dict, postprocess_rstrip);
g_variant_builder_add_value (&builder, g_variant_dict_end (&dict));
}
}
ipc_service_complete_get_process_info (service, invocation, g_variant_builder_end (&builder));
res = helpers_get_process_info (attributes);
ipc_service_complete_get_process_info (service, invocation, res);
return TRUE;
}

View File

@ -143,6 +143,7 @@ test_process (void)
filter = sysprof_model_filter_new (G_LIST_MODEL (model));
sysprof_process_model_set_no_proxy (model, TRUE);
sysprof_process_model_reload (model);
for (guint i = 0; i < G_N_ELEMENTS (searches); i++)

View File

@ -78,6 +78,7 @@ main (gint argc,
gtk_container_add (GTK_CONTAINER (scroller), list);
model = sysprof_process_model_new ();
sysprof_process_model_set_no_proxy (model, TRUE);
filter = sysprof_model_filter_new (G_LIST_MODEL (model));
gtk_list_box_bind_model (GTK_LIST_BOX (list), G_LIST_MODEL (filter), create_row, NULL, NULL);