forked from Mirrors/flatpak-builder
remote-modify: Implement --update-metadata as a system-helper method
We download the summary and send it to the system helper, it verifies the checksum and applies the changes, with the same polkit permissions required as for an app update (i.e. typically none). This allows us to update metadata automatically, without permission requests.tingping/wmclass
parent
b25987255e
commit
9896005ad0
|
@ -7609,11 +7609,13 @@ flatpak_dir_list_remote_refs (FlatpakDir *self,
|
|||
static GVariant *
|
||||
fetch_remote_summary_file (FlatpakDir *self,
|
||||
const char *remote,
|
||||
GBytes **summary_sig_bytes_out,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
g_autoptr(GError) my_error = NULL;
|
||||
g_autoptr(GBytes) summary_bytes = NULL;
|
||||
g_autoptr(GBytes) summary_sig_bytes = NULL;
|
||||
|
||||
if (error == NULL)
|
||||
error = &my_error;
|
||||
|
@ -7622,10 +7624,13 @@ fetch_remote_summary_file (FlatpakDir *self,
|
|||
return NULL;
|
||||
|
||||
if (!flatpak_dir_remote_fetch_summary (self, remote,
|
||||
&summary_bytes, NULL,
|
||||
&summary_bytes, &summary_sig_bytes,
|
||||
cancellable, error))
|
||||
return NULL;
|
||||
|
||||
|
||||
if (summary_sig_bytes_out != NULL)
|
||||
*summary_sig_bytes_out = g_steal_pointer (&summary_sig_bytes);
|
||||
return g_variant_ref_sink (g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT,
|
||||
summary_bytes, FALSE));
|
||||
}
|
||||
|
@ -7641,7 +7646,7 @@ flatpak_dir_fetch_remote_title (FlatpakDir *self,
|
|||
g_autoptr(GVariant) extensions = NULL;
|
||||
g_autofree char *title = NULL;
|
||||
|
||||
summary = fetch_remote_summary_file (self, remote, cancellable, error);
|
||||
summary = fetch_remote_summary_file (self, remote, NULL, cancellable, error);
|
||||
if (summary == NULL)
|
||||
return NULL;
|
||||
|
||||
|
@ -7669,7 +7674,7 @@ flatpak_dir_fetch_remote_default_branch (FlatpakDir *self,
|
|||
g_autoptr(GVariant) extensions = NULL;
|
||||
g_autofree char *default_branch = NULL;
|
||||
|
||||
summary = fetch_remote_summary_file (self, remote, cancellable, error);
|
||||
summary = fetch_remote_summary_file (self, remote, NULL, cancellable, error);
|
||||
if (summary == NULL)
|
||||
return NULL;
|
||||
|
||||
|
@ -7692,13 +7697,15 @@ flatpak_dir_fetch_remote_summary (FlatpakDir *self,
|
|||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
return fetch_remote_summary_file (self, remote, cancellable, error);
|
||||
return fetch_remote_summary_file (self, remote, NULL, cancellable, error);
|
||||
}
|
||||
|
||||
gboolean
|
||||
flatpak_dir_update_remote_configuration_for_summary (FlatpakDir *self,
|
||||
const char *remote,
|
||||
GVariant *summary,
|
||||
gboolean dry_run,
|
||||
gboolean *has_changed_out,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
|
@ -7778,7 +7785,10 @@ flatpak_dir_update_remote_configuration_for_summary (FlatpakDir *self,
|
|||
i += 2;
|
||||
}
|
||||
|
||||
if (!has_changed)
|
||||
if (has_changed_out)
|
||||
*has_changed_out = has_changed;
|
||||
|
||||
if (dry_run || !has_changed)
|
||||
return TRUE;
|
||||
|
||||
if (flatpak_dir_use_system_helper (self, NULL))
|
||||
|
@ -7820,12 +7830,64 @@ flatpak_dir_update_remote_configuration (FlatpakDir *self,
|
|||
GError **error)
|
||||
{
|
||||
g_autoptr(GVariant) summary = NULL;
|
||||
g_autoptr(GBytes) summary_sig_bytes = NULL;
|
||||
|
||||
summary = fetch_remote_summary_file (self, remote, cancellable, error);
|
||||
summary = fetch_remote_summary_file (self, remote, &summary_sig_bytes, cancellable, error);
|
||||
if (summary == NULL)
|
||||
return FALSE;
|
||||
|
||||
return flatpak_dir_update_remote_configuration_for_summary (self, remote, summary, cancellable, error);
|
||||
if (flatpak_dir_use_system_helper (self, NULL))
|
||||
{
|
||||
gboolean has_changed = FALSE;
|
||||
|
||||
if (!flatpak_dir_update_remote_configuration_for_summary (self, remote, summary, TRUE, &has_changed, cancellable, error))
|
||||
return FALSE;
|
||||
|
||||
if (summary_sig_bytes == NULL)
|
||||
return flatpak_fail (error, _("Can't update remote configuration as user, no GPG signature exist"));
|
||||
|
||||
if (has_changed)
|
||||
{
|
||||
g_autoptr(GBytes) bytes = g_variant_get_data_as_bytes (summary);
|
||||
glnx_fd_close int summary_fd = -1;
|
||||
g_autofree char *summary_path = NULL;
|
||||
glnx_fd_close int summary_sig_fd = -1;
|
||||
g_autofree char *summary_sig_path = NULL;
|
||||
FlatpakSystemHelper *system_helper;
|
||||
const char *installation;
|
||||
|
||||
system_helper = flatpak_dir_get_system_helper (self);
|
||||
g_assert (system_helper != NULL);
|
||||
|
||||
summary_fd = g_file_open_tmp ("remote-summary.XXXXXX", &summary_path, error);
|
||||
if (summary_fd == -1)
|
||||
return FALSE;
|
||||
if (glnx_loop_write (summary_fd, g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes)) < 0)
|
||||
return glnx_throw_errno (error);
|
||||
|
||||
summary_sig_fd = g_file_open_tmp ("remote-summary-sig.XXXXXX", &summary_sig_path, error);
|
||||
if (summary_sig_fd == -1)
|
||||
return FALSE;
|
||||
if (glnx_loop_write (summary_sig_fd, g_bytes_get_data (summary_sig_bytes, NULL), g_bytes_get_size (summary_sig_bytes)) < 0)
|
||||
return glnx_throw_errno (error);
|
||||
|
||||
installation = flatpak_dir_get_id (self);
|
||||
|
||||
g_debug ("Calling system helper: UpdateRemote");
|
||||
if (!flatpak_system_helper_call_update_remote_sync (system_helper, 0, remote,
|
||||
installation ? installation : "",
|
||||
summary_path, summary_sig_path,
|
||||
cancellable, error))
|
||||
return FALSE;
|
||||
|
||||
unlink (summary_path);
|
||||
unlink (summary_sig_path);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return flatpak_dir_update_remote_configuration_for_summary (self, remote, summary, FALSE, NULL, cancellable, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
|
|
@ -94,6 +94,12 @@ typedef enum {
|
|||
|
||||
#define FLATPAK_HELPER_CONFIGURE_REMOTE_FLAGS_ALL (FLATPAK_HELPER_CONFIGURE_REMOTE_FLAGS_FORCE_REMOVE)
|
||||
|
||||
typedef enum {
|
||||
FLATPAK_HELPER_UPDATE_REMOTE_FLAGS_NONE = 0,
|
||||
} FlatpakHelperUpdateRemoteFlags;
|
||||
|
||||
#define FLATPAK_HELPER_UPDATE_REMOTE_FLAGS_ALL (0)
|
||||
|
||||
typedef enum {
|
||||
FLATPAK_PULL_FLAGS_NONE = 0,
|
||||
FLATPAK_PULL_FLAGS_DOWNLOAD_EXTRA_DATA = 1 << 0,
|
||||
|
@ -528,6 +534,8 @@ gboolean flatpak_dir_update_remote_configuration (FlatpakDir *self,
|
|||
gboolean flatpak_dir_update_remote_configuration_for_summary (FlatpakDir *self,
|
||||
const char *remote,
|
||||
GVariant *summary,
|
||||
gboolean dry_run,
|
||||
gboolean *has_changed_out,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
gboolean flatpak_dir_fetch_ref_cache (FlatpakDir *self,
|
||||
|
|
|
@ -99,6 +99,14 @@
|
|||
<arg type='s' name='installation' direction='in'/>
|
||||
</method>
|
||||
|
||||
<method name="UpdateRemote">
|
||||
<arg type='u' name='flags' direction='in'/>
|
||||
<arg type='s' name='remote' direction='in'/>
|
||||
<arg type='s' name='installation' direction='in'/>
|
||||
<arg type='ay' name='summary_path' direction='in'/>
|
||||
<arg type='ay' name='summary_sig_path' direction='in'/>
|
||||
</method>
|
||||
|
||||
</interface>
|
||||
|
||||
</node>
|
||||
|
|
|
@ -677,6 +677,100 @@ handle_configure_remote (FlatpakSystemHelper *object,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
handle_update_remote (FlatpakSystemHelper *object,
|
||||
GDBusMethodInvocation *invocation,
|
||||
guint arg_flags,
|
||||
const gchar *arg_remote,
|
||||
const gchar *arg_installation,
|
||||
const gchar *arg_summary_path,
|
||||
const gchar *arg_summary_sig_path)
|
||||
{
|
||||
g_autoptr(FlatpakDir) system = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(GKeyFile) config = g_key_file_new ();
|
||||
g_autofree char *group = g_strdup_printf ("remote \"%s\"", arg_remote);
|
||||
g_autoptr(GBytes) gpg_data = NULL;
|
||||
gboolean force_remove;
|
||||
char *summary_data = NULL;
|
||||
gsize summary_size;
|
||||
g_autoptr(GBytes) summary_bytes = NULL;
|
||||
g_autoptr(GVariant) summary = NULL;
|
||||
char *summary_sig_data = NULL;
|
||||
gsize summary_sig_size;
|
||||
g_autoptr(GBytes) summary_sig_bytes = NULL;
|
||||
g_autoptr(OstreeGpgVerifyResult) gpg_result = NULL;
|
||||
|
||||
g_debug ("UpdateRemote %u %s %s %s %s", arg_flags, arg_remote, arg_installation, arg_summary_path, arg_summary_sig_path);
|
||||
|
||||
system = dir_get_system (arg_installation, &error);
|
||||
if (system == NULL)
|
||||
{
|
||||
g_dbus_method_invocation_return_gerror (invocation, error);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (*arg_remote == 0 || strchr (arg_remote, '/') != NULL)
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
|
||||
"Invalid remote name: %s", arg_remote);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if ((arg_flags & ~FLATPAK_HELPER_UPDATE_REMOTE_FLAGS_ALL) != 0)
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
|
||||
"Unsupported flags enabled: 0x%x", (arg_flags & ~FLATPAK_HELPER_UPDATE_REMOTE_FLAGS_ALL));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!flatpak_dir_ensure_repo (system, NULL, &error))
|
||||
{
|
||||
g_dbus_method_invocation_return_gerror (invocation, error);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!g_file_get_contents (arg_summary_path, &summary_data, &summary_size, &error))
|
||||
{
|
||||
g_dbus_method_invocation_return_gerror (invocation, error);
|
||||
return TRUE;
|
||||
}
|
||||
summary_bytes = g_bytes_new_take (summary_data, summary_size);
|
||||
|
||||
if (!g_file_get_contents (arg_summary_sig_path, &summary_sig_data, &summary_sig_size, &error))
|
||||
{
|
||||
g_dbus_method_invocation_return_gerror (invocation, error);
|
||||
return TRUE;
|
||||
}
|
||||
summary_sig_bytes = g_bytes_new_take (summary_sig_data, summary_sig_size);
|
||||
|
||||
gpg_result = ostree_repo_verify_summary (flatpak_dir_get_repo (system),
|
||||
arg_remote,
|
||||
summary_bytes,
|
||||
summary_sig_bytes,
|
||||
NULL, &error);
|
||||
if (gpg_result == NULL ||
|
||||
!ostree_gpg_verify_result_require_valid_signature (gpg_result, &error))
|
||||
{
|
||||
g_dbus_method_invocation_return_gerror (invocation, error);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
summary = g_variant_ref_sink (g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT,
|
||||
summary_bytes, FALSE));
|
||||
if (!flatpak_dir_update_remote_configuration_for_summary (system, arg_remote, summary,
|
||||
FALSE, NULL, NULL, &error))
|
||||
{
|
||||
g_dbus_method_invocation_return_gerror (invocation, error);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
flatpak_system_helper_complete_update_remote (object, invocation);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
flatpak_authorize_method_handler (GDBusInterfaceSkeleton *interface,
|
||||
GDBusMethodInvocation *invocation,
|
||||
|
@ -778,6 +872,16 @@ flatpak_authorize_method_handler (GDBusInterfaceSkeleton *interface,
|
|||
|
||||
action = "org.freedesktop.Flatpak.configure-remote";
|
||||
|
||||
polkit_details_insert (details, "remote", remote);
|
||||
}
|
||||
else if (g_strcmp0 (method_name, "UpdateRemote") == 0)
|
||||
{
|
||||
const char *remote;
|
||||
|
||||
g_variant_get_child (parameters, 1, "&s", &remote);
|
||||
|
||||
action = "org.freedesktop.Flatpak.update-remote";
|
||||
|
||||
polkit_details_insert (details, "remote", remote);
|
||||
}
|
||||
|
||||
|
@ -832,6 +936,7 @@ on_bus_acquired (GDBusConnection *connection,
|
|||
g_signal_connect (helper, "handle-uninstall", G_CALLBACK (handle_uninstall), NULL);
|
||||
g_signal_connect (helper, "handle-install-bundle", G_CALLBACK (handle_install_bundle), NULL);
|
||||
g_signal_connect (helper, "handle-configure-remote", G_CALLBACK (handle_configure_remote), NULL);
|
||||
g_signal_connect (helper, "handle-update-remote", G_CALLBACK (handle_update_remote), NULL);
|
||||
|
||||
g_signal_connect (helper, "g-authorize-method",
|
||||
G_CALLBACK (flatpak_authorize_method_handler),
|
||||
|
|
|
@ -83,6 +83,21 @@
|
|||
</defaults>
|
||||
</action>
|
||||
|
||||
<action id="org.freedesktop.Flatpak.update-remote">
|
||||
<!-- SECURITY:
|
||||
- Normal users do not need authentication to update metadata
|
||||
from signed repositories.
|
||||
-->
|
||||
<description>Update remote metadata</description>
|
||||
<message>Authentication is required to update remote info</message>
|
||||
<icon_name>package-x-generic</icon_name>
|
||||
<defaults>
|
||||
<allow_any>auth_admin</allow_any>
|
||||
<allow_inactive>auth_admin</allow_inactive>
|
||||
<allow_active>yes</allow_active>
|
||||
</defaults>
|
||||
</action>
|
||||
|
||||
<action id="org.freedesktop.Flatpak.install-bundle">
|
||||
<description>Install bundle</description>
|
||||
<message>Authentication is required to install software</message>
|
||||
|
|
Loading…
Reference in New Issue