system-helper: Support add/modify/delete of remotes

tingping/wmclass
Alexander Larsson 2016-05-13 16:23:43 +02:00
parent 4a8a225447
commit 1504f7bd7f
5 changed files with 191 additions and 1 deletions

View File

@ -4163,6 +4163,30 @@ flatpak_dir_remove_remote (FlatpakDir *self,
GHashTableIter hash_iter;
gpointer key;
if (flatpak_dir_use_system_helper (self))
{
FlatpakSystemHelper *system_helper;
g_autoptr(GVariant) gpg_data_v = NULL;
FlatpakHelperConfigureRemoteFlags flags = 0;
gpg_data_v = g_variant_ref_sink (g_variant_new_from_data (G_VARIANT_TYPE ("ay"), "", 0, TRUE, NULL, NULL));
system_helper = flatpak_dir_get_system_helper (self);
g_assert (system_helper != NULL);
if (force_remove)
flags |= FLATPAK_HELPER_CONFIGURE_REMOTE_FLAGS_FORCE_REMOVE;
if (!flatpak_system_helper_call_configure_remote_sync (system_helper,
flags, remote_name,
"",
gpg_data_v,
cancellable, error))
return FALSE;
return TRUE;
}
if (!flatpak_dir_ensure_repo (self, cancellable, error))
return FALSE;
@ -4222,6 +4246,17 @@ flatpak_dir_remove_remote (FlatpakDir *self,
return TRUE;
}
static GVariant *
variant_new_ay_bytes (GBytes *bytes)
{
gsize size;
gconstpointer data;
data = g_bytes_get_data (bytes, &size);
g_bytes_ref (bytes);
return g_variant_ref_sink (g_variant_new_from_data (G_VARIANT_TYPE ("ay"), data, size,
TRUE, (GDestroyNotify)g_bytes_unref, bytes));
}
gboolean
flatpak_dir_modify_remote (FlatpakDir *self,
const char *remote_name,
@ -4246,6 +4281,31 @@ flatpak_dir_modify_remote (FlatpakDir *self,
return flatpak_fail (error, "No configuration for remote %s specified",
remote_name);
if (flatpak_dir_use_system_helper (self))
{
FlatpakSystemHelper *system_helper;
g_autofree char *config_data = g_key_file_to_data (config, NULL, NULL);
g_autoptr(GVariant) gpg_data_v = NULL;
if (gpg_data != NULL)
gpg_data_v = variant_new_ay_bytes (gpg_data);
else
gpg_data_v = g_variant_ref_sink (g_variant_new_from_data (G_VARIANT_TYPE ("ay"), "", 0, TRUE, NULL, NULL));
system_helper = flatpak_dir_get_system_helper (self);
g_assert (system_helper != NULL);
if (!flatpak_system_helper_call_configure_remote_sync (system_helper,
0, remote_name,
config_data,
gpg_data_v,
cancellable, error))
return FALSE;
return TRUE;
}
metalink = g_key_file_get_string (config, group, "metalink", NULL);
if (metalink != NULL && *metalink != 0)
url = g_strconcat ("metalink=", metalink, NULL);

View File

@ -55,6 +55,13 @@ typedef enum {
#define FLATPAK_HELPER_UNINSTALL_FLAGS_ALL (FLATPAK_HELPER_UNINSTALL_FLAGS_KEEP_REF | FLATPAK_HELPER_UNINSTALL_FLAGS_FORCE_REMOVE)
typedef enum {
FLATPAK_HELPER_CONFIGURE_REMOTE_FLAGS_NONE = 0,
FLATPAK_HELPER_CONFIGURE_REMOTE_FLAGS_FORCE_REMOVE = 1 << 0,
} FlatpakHelperConfigureRemoteFlags;
#define FLATPAK_HELPER_CONFIGURE_REMOTE_FLAGS_ALL (FLATPAK_HELPER_CONFIGURE_REMOTE_FLAGS_FORCE_REMOVE)
GQuark flatpak_dir_error_quark (void);
/**

View File

@ -51,6 +51,15 @@
<arg type='s' name='ref' direction='in'/>
</method>
<method name="ConfigureRemote">
<arg type='u' name='flags' direction='in'/>
<arg type='s' name='remote' direction='in'/>
<arg type='s' name='config' direction='in'/>
<arg type='ay' name='gpg_key' direction='in'>
<annotation name="org.gtk.GDBus.C.ForceGVariant" value="true"/>
</arg>
</method>
</interface>
</node>

View File

@ -303,7 +303,6 @@ handle_uninstall (FlatpakSystemHelper *object,
{
g_autoptr(FlatpakDir) system = flatpak_dir_get_system ();
g_autoptr(GError) error = NULL;
g_autoptr(GMainContext) main_context = NULL;
g_debug ("Uninstall %u %s", arg_flags, arg_ref);
@ -327,6 +326,85 @@ handle_uninstall (FlatpakSystemHelper *object,
}
flatpak_system_helper_complete_uninstall (object, invocation);
return TRUE;
}
static gboolean
handle_configure_remote (FlatpakSystemHelper *object,
GDBusMethodInvocation *invocation,
guint arg_flags,
const gchar *arg_remote,
const gchar *arg_config,
GVariant *arg_gpg_key)
{
g_autoptr(FlatpakDir) system = flatpak_dir_get_system ();
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;
g_debug ("ConfigureRemote %u %s", arg_flags, arg_remote);
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_CONFIGURE_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_CONFIGURE_REMOTE_FLAGS_ALL));
return TRUE;
}
if (!g_key_file_load_from_data (config, arg_config, strlen (arg_config),
G_KEY_FILE_NONE, &error))
{
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
"Invalid config: %s\n", error->message);
return TRUE;
}
if (!flatpak_dir_ensure_repo (system, NULL, &error))
{
g_dbus_method_invocation_return_gerror (invocation, error);
return TRUE;
}
if (g_variant_get_size (arg_gpg_key) > 0)
gpg_data = g_variant_get_data_as_bytes (arg_gpg_key);
force_remove = (arg_flags & FLATPAK_HELPER_CONFIGURE_REMOTE_FLAGS_FORCE_REMOVE) != 0;
if (g_key_file_has_group (config, group))
{
/* Add/Modify */
if (!flatpak_dir_modify_remote (system, arg_remote, config,
gpg_data, NULL, &error))
{
g_dbus_method_invocation_return_gerror (invocation, error);
return TRUE;
}
}
else
{
/* Remove */
if (!flatpak_dir_remove_remote (system,
force_remove,
arg_remote,
NULL, &error))
{
g_dbus_method_invocation_return_gerror (invocation, error);
return TRUE;
}
}
flatpak_system_helper_complete_configure_remote (object, invocation);
return TRUE;
}
@ -445,6 +523,30 @@ flatpak_authorize_method_handler (GDBusInterfaceSkeleton *interface,
details = polkit_details_new ();
polkit_details_insert (details, "ref", ref);
result = polkit_authority_check_authorization_sync (authority, subject,
action, details,
POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION,
NULL, &error);
if (result == NULL)
{
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
"Authorization error: %s", error->message);
return FALSE;
}
authorized = polkit_authorization_result_get_is_authorized (result);
}
else if (g_strcmp0 (method_name, "ConfigureRemote") == 0)
{
const char *remote;
g_variant_get_child (parameters, 1, "&s", &remote);
action = "org.freedesktop.Flatpak.configure-remote";
details = polkit_details_new ();
polkit_details_insert (details, "remote", remote);
result = polkit_authority_check_authorization_sync (authority, subject,
action, details,
POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION,
@ -489,6 +591,7 @@ on_bus_acquired (GDBusConnection *connection,
g_signal_connect (helper, "handle-deploy", G_CALLBACK (handle_deploy), NULL);
g_signal_connect (helper, "handle-deploy-appstream", G_CALLBACK (handle_deploy_appstream), NULL);
g_signal_connect (helper, "handle-uninstall", G_CALLBACK (handle_uninstall), NULL);
g_signal_connect (helper, "handle-configure-remote", G_CALLBACK (handle_configure_remote), NULL);
g_signal_connect (helper, "g-authorize-method",
G_CALLBACK (flatpak_authorize_method_handler),

View File

@ -105,6 +105,17 @@
</defaults>
</action>
<action id="org.freedesktop.Flatpak.configure-remote">
<_description>Configure Remote</_description>
<_message>Authentication is required to configure software repositories</_message>
<icon_name>package-x-generic</icon_name>
<defaults>
<allow_any>auth_admin</allow_any>
<allow_inactive>auth_admin</allow_inactive>
<allow_active>auth_admin</allow_active>
</defaults>
</action>
<action id="org.freedesktop.Flatpak.appstream-update">
<!-- SECURITY:
- Normal users do not require admin authentication to update