mirror of
https://git.proxmox.com/git/fwupd
synced 2025-08-06 04:57:59 +00:00
Provide a way for clients to add new firmware metadata to the system cache
This is only possible if the metadata has been signed by a key that we trust.
This commit is contained in:
parent
595f59c8e5
commit
ae0efdc5a7
@ -79,6 +79,7 @@ find %{buildroot} -name '*.la' -exec rm -f {} ';'
|
||||
%{_libexecdir}/fwupd
|
||||
%{_bindir}/fwupdmgr
|
||||
%{_sysconfdir}/pki/fwupd
|
||||
%{_sysconfdir}/pki/fwupd-metadata
|
||||
%{_sysconfdir}/dbus-1/system.d/org.freedesktop.fwupd.conf
|
||||
%{_datadir}/dbus-1/interfaces/org.freedesktop.fwupd.xml
|
||||
%{_datadir}/polkit-1/actions/org.freedesktop.fwupd.policy
|
||||
@ -90,6 +91,9 @@ find %{buildroot} -name '*.la' -exec rm -f {} ';'
|
||||
%dir %{_localstatedir}/lib/fwupd
|
||||
%{_libdir}/lib*.so.*
|
||||
%{_libdir}/girepository-1.0/*.typelib
|
||||
%dir %{_localstatedir}/cache/app-info
|
||||
%dir %{_localstatedir}/cache/app-info/icons
|
||||
%dir %{_localstatedir}/cache/app-info/xmls
|
||||
|
||||
%files devel
|
||||
%{_includedir}/fwupd-1
|
||||
|
110
data/pki/GPG-KEY-Linux-Vendor-Firmware-Service
Normal file
110
data/pki/GPG-KEY-Linux-Vendor-Firmware-Service
Normal file
@ -0,0 +1,110 @@
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: GnuPG v1
|
||||
|
||||
mQENBEgu03ABCAC+4WHuoCNAN0G1jHRSF2DAphtTIuZkhKbd3C1BMzvU40O5cwhW
|
||||
LWILM1IYa4YwYI77tJsLi1Hax9D59NNAKdESqsKGuN/QbeXuAD3qpKA6B51lZD9k
|
||||
jPizCl+s3q+NxaJb8Rk92yocYyuolNii5qrkD1YazcbFCkuBX2wg7q1hqU8YaGNx
|
||||
Q3SuKf4Rkkg9T/6mCz6hEE8z4sVLncFY7pqt6ch+ycGz4MWGo9Eh51HvYi2QmSf3
|
||||
6OjNrKHp1LwPF1V/LYI9dHPXfeWE3tgco8hhDsgYaG2W3yhk8Pn5BhnNGgmiCXQs
|
||||
Allf7a3U/leXgOMTVJNvx+8yNrHRuI2YZMRhABEBAAG0JFJpY2hhcmQgSHVnaGVz
|
||||
IDxyaWNoYXJkQGh1Z2hzaWUuY29tPokBNgQTAQIAIAUCSC7TcAIbLwYLCQgHAwIE
|
||||
FQIIAwQWAgMBAh4BAheAAAoJEBesuo36lw4XBVIH/RKjtx2Xk1782CGX9PZnwLaC
|
||||
krfPTDlcusAFwqtV9AiECenXGLS3A3Kcq6BOJ9wCh1FF80mRJMwRn2ONvHEkg1Dh
|
||||
8amv4YD9y4r6mjA6tyk7MOPNCSc8ZYZHUl/RacHAOePnKjMWSsU7n6v+RTpjOWR5
|
||||
JjyMlIHv7K9h6KEx5VCLaDXLxluQvPc8uYBZJlMBa3K/pGS18RJKKrw0l5/8p5tY
|
||||
uWPxL4Zay7SWdGiiy3EPcq3GJXu85I1x+LbMbq69BjwQt28B/5iMD0RCbYF0mHG2
|
||||
6iQNU1Gr8+BX2+CFXLSbo1rPExsrOO3Maz7OjX4VathnqS0h9I+Q3dFlnks6Ic/R
|
||||
zxnPFwEQAAEBAAAAAAAAAAAAAAAA/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgG
|
||||
BgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAx
|
||||
NDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIy
|
||||
MjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCACQAH0DASIA
|
||||
AhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgED
|
||||
AwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2Jy
|
||||
ggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1
|
||||
dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJ
|
||||
ytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAA
|
||||
AAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJB
|
||||
UQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNE
|
||||
RUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJma
|
||||
oqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP0
|
||||
9fb3+Pn6/9oADAMBAAIRAxEAPwDtVhmb0FSLaOfvNV4LS4rmJKq2a9yakFrGO1WA
|
||||
Kpapq1lo1o11fTrFGo6nv7CgLFkQoozgACud1nxx4d0HetzfRtMv/LGL5m/SvLvG
|
||||
HxR1HVGe10gm1tPus4Hzv757CvOJS8h8yR9xPU55NUo3K5e57VL8bbBXYQaVM4/h
|
||||
LSAZ/Sn23xptHb9/pMyJ6pICf6V4aGyflFWYmJGGxVOBSSPoTTvit4cvZFSVprVj
|
||||
xmVOPzGa7OzvbW/gWe0uI5o25DRsCK+T9o525I/lVvTPEOqaBdiawupIWB5A6N9R
|
||||
0NTyvoJxPq7FGK868G/FSw1xI7XVGjtb8naMcI59vSvRlIZQykEHoRUkNCVn6r/q
|
||||
R9a0qztUH7taBDtLGLXPvV2q2nDFoPrVrFAFelxSCgnAJpDMXxH4kttAtCzkGZlJ
|
||||
Re3414vrfiX+3b5pLr992CEkKPoBS/EPWJrzxDMjsQinaoBB4rQ8DeF47krf3ceR
|
||||
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
|
||||
vEI5YQ==
|
||||
=/V/G
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
@ -1,4 +1,7 @@
|
||||
pkidir = $(sysconfdir)/pki/fwupd
|
||||
dist_pki_DATA = GPG-KEY-Hughski-Limited
|
||||
|
||||
pkimetadatadir = $(sysconfdir)/pki/fwupd-metadata
|
||||
dist_pkimetadata_DATA = GPG-KEY-Linux-Vendor-Firmware-Service
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
||||
|
@ -166,6 +166,8 @@ install-data-hook:
|
||||
if test -w $(DESTDIR)$(prefix)/; then \
|
||||
mkdir -p $(DESTDIR)$(localstatedir)/lib/fwupd; \
|
||||
chmod 0755 $(DESTDIR)$(localstatedir)/lib/fwupd; \
|
||||
mkdir -p $(DESTDIR)$(localstatedir)/cache/app-info/xmls; \
|
||||
mkdir -p $(DESTDIR)$(localstatedir)/cache/app-info/icons; \
|
||||
fi
|
||||
|
||||
TESTS = fu-self-test
|
||||
|
@ -321,6 +321,94 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_keyring_verify_data:
|
||||
**/
|
||||
gboolean
|
||||
fu_keyring_verify_data (FuKeyring *keyring,
|
||||
GBytes *payload,
|
||||
GBytes *payload_signature,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = TRUE;
|
||||
gpgme_data_t data = NULL;
|
||||
gpgme_data_t sig = NULL;
|
||||
gpgme_error_t rc;
|
||||
gpgme_signature_t s;
|
||||
gpgme_verify_result_t result;
|
||||
|
||||
g_return_val_if_fail (FU_IS_KEYRING (keyring), FALSE);
|
||||
g_return_val_if_fail (payload != NULL, FALSE);
|
||||
g_return_val_if_fail (payload_signature != NULL, FALSE);
|
||||
|
||||
/* setup context */
|
||||
if (!fu_keyring_setup (keyring, error))
|
||||
return FALSE;
|
||||
|
||||
/* load file data */
|
||||
rc = gpgme_data_new_from_mem (&data,
|
||||
g_bytes_get_data (payload, NULL),
|
||||
g_bytes_get_size (payload), 0);
|
||||
if (rc != GPG_ERR_NO_ERROR) {
|
||||
ret = FALSE;
|
||||
g_set_error (error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_INTERNAL,
|
||||
"failed to load data: %s",
|
||||
gpgme_strerror (rc));
|
||||
goto out;
|
||||
}
|
||||
rc = gpgme_data_new_from_mem (&sig,
|
||||
g_bytes_get_data (payload_signature, NULL),
|
||||
g_bytes_get_size (payload_signature), 0);
|
||||
if (rc != GPG_ERR_NO_ERROR) {
|
||||
ret = FALSE;
|
||||
g_set_error (error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_INTERNAL,
|
||||
"failed to load signature: %s",
|
||||
gpgme_strerror (rc));
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* verify */
|
||||
rc = gpgme_op_verify (keyring->priv->ctx, sig, data, NULL);
|
||||
if (rc != GPG_ERR_NO_ERROR) {
|
||||
ret = FALSE;
|
||||
g_set_error (error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_INTERNAL,
|
||||
"failed to verify data: %s",
|
||||
gpgme_strerror (rc));
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
/* verify the result */
|
||||
result = gpgme_op_verify_result (keyring->priv->ctx);
|
||||
if (result == NULL) {
|
||||
ret = FALSE;
|
||||
g_set_error_literal (error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_INTERNAL,
|
||||
"no result record from libgpgme");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* look at each signature */
|
||||
for (s = result->signatures; s != NULL ; s = s->next ) {
|
||||
ret = fu_keyring_check_signature (s, error);
|
||||
if (!ret)
|
||||
goto out;
|
||||
}
|
||||
out:
|
||||
if (data != NULL)
|
||||
gpgme_data_release (data);
|
||||
if (sig != NULL)
|
||||
gpgme_data_release (sig);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_keyring_class_init:
|
||||
**/
|
||||
|
@ -63,6 +63,10 @@ gboolean fu_keyring_verify_file (FuKeyring *keyring,
|
||||
const gchar *filename,
|
||||
const gchar *signature,
|
||||
GError **error);
|
||||
gboolean fu_keyring_verify_data (FuKeyring *keyring,
|
||||
GBytes *payload,
|
||||
GBytes *payload_signature,
|
||||
GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
133
src/fu-main.c
133
src/fu-main.c
@ -26,6 +26,7 @@
|
||||
#include <glib/gstdio.h>
|
||||
#include <gio/gio.h>
|
||||
#include <gio/gunixfdlist.h>
|
||||
#include <gio/gunixinputstream.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <locale.h>
|
||||
#include <polkit/polkit.h>
|
||||
@ -36,6 +37,7 @@
|
||||
#include "fu-cleanup.h"
|
||||
#include "fu-debug.h"
|
||||
#include "fu-device.h"
|
||||
#include "fu-keyring.h"
|
||||
#include "fu-pending.h"
|
||||
#include "fu-provider.h"
|
||||
#include "fu-provider-usb.h"
|
||||
@ -566,6 +568,101 @@ fu_main_get_action_id_for_device (FuMainAuthHelper *helper)
|
||||
return "org.freedesktop.fwupd.update-internal";
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_main_daemon_update_metadata:
|
||||
*
|
||||
* Supports optionally GZipped AppStream files up to 1MiB in size.
|
||||
**/
|
||||
static gboolean
|
||||
fu_main_daemon_update_metadata (gint fd, gint fd_sig, GError **error)
|
||||
{
|
||||
guint8 magic[2];
|
||||
_cleanup_bytes_unref_ GBytes *bytes = NULL;
|
||||
_cleanup_bytes_unref_ GBytes *bytes_raw = NULL;
|
||||
_cleanup_bytes_unref_ GBytes *bytes_sig = NULL;
|
||||
_cleanup_object_unref_ AsStore *store = NULL;
|
||||
_cleanup_object_unref_ FuKeyring *kr = NULL;
|
||||
_cleanup_object_unref_ GConverter *converter = NULL;
|
||||
_cleanup_object_unref_ GFile *file = NULL;
|
||||
_cleanup_object_unref_ GInputStream *stream_buf = NULL;
|
||||
_cleanup_object_unref_ GInputStream *stream_fd = NULL;
|
||||
_cleanup_object_unref_ GInputStream *stream = NULL;
|
||||
_cleanup_object_unref_ GInputStream *stream_sig = NULL;
|
||||
|
||||
/* open existing file if it exists */
|
||||
store = as_store_new ();
|
||||
file = g_file_new_for_path ("/var/cache/app-info/xmls/fwupd.xml");
|
||||
if (g_file_query_exists (file, NULL)) {
|
||||
if (!as_store_from_file (store, file, NULL, NULL, error))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* read the entire file into memory */
|
||||
stream_fd = g_unix_input_stream_new (fd, TRUE);
|
||||
bytes_raw = g_input_stream_read_bytes (stream_fd, 0x100000, NULL, error);
|
||||
if (bytes_raw == NULL)
|
||||
return FALSE;
|
||||
stream_buf = g_memory_input_stream_new ();
|
||||
g_memory_input_stream_add_bytes (G_MEMORY_INPUT_STREAM (stream_buf), bytes_raw);
|
||||
|
||||
/* peek the file type and get data */
|
||||
if (g_input_stream_read (stream_buf, magic, 2, NULL, error) == -1)
|
||||
return FALSE;
|
||||
if (magic[0] == 0x1f && magic[1] == 0x8b) {
|
||||
g_debug ("using GZip decompressor for data");
|
||||
if (!g_seekable_seek (G_SEEKABLE (stream_buf), 0, G_SEEK_SET, NULL, error))
|
||||
return FALSE;
|
||||
converter = G_CONVERTER (g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP));
|
||||
stream = g_converter_input_stream_new (stream_buf, converter);
|
||||
bytes = g_input_stream_read_bytes (stream, 0x100000, NULL, error);
|
||||
if (bytes == NULL)
|
||||
return FALSE;
|
||||
} else if (magic[0] == '<' && magic[1] == '?') {
|
||||
g_debug ("using no decompressor for data");
|
||||
bytes = g_bytes_ref (bytes_raw);
|
||||
} else {
|
||||
g_set_error (error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_INVALID_FILE,
|
||||
"file type '0x%02x,0x%02x' not supported",
|
||||
magic[0], magic[1]);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* read signature */
|
||||
stream_sig = g_unix_input_stream_new (fd_sig, TRUE);
|
||||
bytes_sig = g_input_stream_read_bytes (stream_sig, 0x800, NULL, error);
|
||||
if (bytes_sig == NULL)
|
||||
return FALSE;
|
||||
|
||||
/* verify file */
|
||||
kr = fu_keyring_new ();
|
||||
if (!fu_keyring_add_public_keys (kr, "/etc/pki/fwupd-metadata", error))
|
||||
return FALSE;
|
||||
if (!fu_keyring_verify_data (kr, bytes_raw, bytes_sig, error))
|
||||
return FALSE;
|
||||
|
||||
/* merge in the new contents */
|
||||
g_debug ("Store was %i size", as_store_get_size (store));
|
||||
if (!as_store_from_xml (store,
|
||||
g_bytes_get_data (bytes, NULL), -1,
|
||||
NULL, error))
|
||||
return FALSE;
|
||||
g_debug ("Store now %i size", as_store_get_size (store));
|
||||
|
||||
/* save the new file */
|
||||
as_store_set_api_version (store, 0.9);
|
||||
if (!as_store_to_file (store, file,
|
||||
AS_NODE_TO_XML_FLAG_ADD_HEADER |
|
||||
AS_NODE_TO_XML_FLAG_FORMAT_MULTILINE |
|
||||
AS_NODE_TO_XML_FLAG_FORMAT_INDENT,
|
||||
NULL, error)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_main_daemon_method_call:
|
||||
**/
|
||||
@ -648,6 +745,42 @@ fu_main_daemon_method_call (GDBusConnection *connection, const gchar *sender,
|
||||
return;
|
||||
}
|
||||
|
||||
/* return '' */
|
||||
if (g_strcmp0 (method_name, "UpdateMetadata") == 0) {
|
||||
GDBusMessage *message;
|
||||
GUnixFDList *fd_list;
|
||||
gint fd_data;
|
||||
gint fd_sig;
|
||||
_cleanup_error_free_ GError *error = NULL;
|
||||
|
||||
message = g_dbus_method_invocation_get_message (invocation);
|
||||
fd_list = g_dbus_message_get_unix_fd_list (message);
|
||||
if (fd_list == NULL || g_unix_fd_list_get_length (fd_list) != 2) {
|
||||
g_dbus_method_invocation_return_error (invocation,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_INTERNAL,
|
||||
"invalid handle");
|
||||
return;
|
||||
}
|
||||
fd_data = g_unix_fd_list_get (fd_list, 0, &error);
|
||||
if (fd_data < 0) {
|
||||
g_dbus_method_invocation_return_gerror (invocation, error);
|
||||
return;
|
||||
}
|
||||
fd_sig = g_unix_fd_list_get (fd_list, 1, &error);
|
||||
if (fd_sig < 0) {
|
||||
g_dbus_method_invocation_return_gerror (invocation, error);
|
||||
return;
|
||||
}
|
||||
if (!fu_main_daemon_update_metadata (fd_data, fd_sig, &error)) {
|
||||
g_prefix_error (&error, "failed to update metadata: ");
|
||||
g_dbus_method_invocation_return_gerror (invocation, error);
|
||||
return;
|
||||
}
|
||||
g_dbus_method_invocation_return_value (invocation, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
/* return '' */
|
||||
if (g_strcmp0 (method_name, "Update") == 0) {
|
||||
FuDeviceItem *item = NULL;
|
||||
|
@ -776,6 +776,84 @@ fu_util_clear_results (FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_util_update_metadata:
|
||||
**/
|
||||
static gboolean
|
||||
fu_util_update_metadata (FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
{
|
||||
GVariant *body;
|
||||
gint fd;
|
||||
gint fd_sig;
|
||||
_cleanup_object_unref_ GDBusMessage *request = NULL;
|
||||
_cleanup_object_unref_ GUnixFDList *fd_list = NULL;
|
||||
|
||||
if (g_strv_length (values) != 2) {
|
||||
g_set_error_literal (error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_INTERNAL,
|
||||
"Invalid arguments: expected 'filename.xml' 'filename.xml.asc'");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* open file */
|
||||
fd = open (values[0], O_RDONLY);
|
||||
if (fd < 0) {
|
||||
g_set_error (error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_INVALID_FILE,
|
||||
"failed to open %s",
|
||||
values[0]);
|
||||
return FALSE;
|
||||
}
|
||||
fd_sig = open (values[1], O_RDONLY);
|
||||
if (fd_sig < 0) {
|
||||
g_set_error (error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_INVALID_FILE,
|
||||
"failed to open %s",
|
||||
values[1]);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* set out of band file descriptor */
|
||||
fd_list = g_unix_fd_list_new ();
|
||||
g_unix_fd_list_append (fd_list, fd, NULL);
|
||||
g_unix_fd_list_append (fd_list, fd_sig, NULL);
|
||||
request = g_dbus_message_new_method_call (FWUPD_DBUS_SERVICE,
|
||||
FWUPD_DBUS_PATH,
|
||||
FWUPD_DBUS_INTERFACE,
|
||||
"UpdateMetadata");
|
||||
g_dbus_message_set_unix_fd_list (request, fd_list);
|
||||
|
||||
/* g_unix_fd_list_append did a dup() already */
|
||||
close (fd);
|
||||
close (fd_sig);
|
||||
|
||||
/* send message */
|
||||
body = g_variant_new ("(hh)", fd, fd_sig);
|
||||
g_dbus_message_set_body (request, body);
|
||||
g_dbus_connection_send_message_with_reply (priv->conn,
|
||||
request,
|
||||
G_DBUS_SEND_MESSAGE_FLAGS_NONE,
|
||||
-1,
|
||||
NULL,
|
||||
NULL,
|
||||
fu_util_update_cb,
|
||||
priv);
|
||||
g_main_loop_run (priv->loop);
|
||||
if (priv->message == NULL) {
|
||||
g_dbus_error_strip_remote_error (priv->error);
|
||||
g_propagate_error (error, priv->error);
|
||||
return FALSE;
|
||||
}
|
||||
if (g_dbus_message_to_gerror (priv->message, error)) {
|
||||
g_dbus_error_strip_remote_error (*error);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_util_get_results:
|
||||
**/
|
||||
@ -1061,6 +1139,12 @@ main (int argc, char *argv[])
|
||||
/* TRANSLATORS: command description */
|
||||
_("Gets the results from the last update"),
|
||||
fu_util_get_results);
|
||||
fu_util_add (priv->cmd_array,
|
||||
"update-metadata",
|
||||
NULL,
|
||||
/* TRANSLATORS: command description */
|
||||
_("Updates metadata"),
|
||||
fu_util_update_metadata);
|
||||
|
||||
/* sort by command name */
|
||||
g_ptr_array_sort (priv->cmd_array,
|
||||
|
@ -169,6 +169,35 @@
|
||||
</arg>
|
||||
</method>
|
||||
|
||||
<!--***********************************************************-->
|
||||
<method name='UpdateMetadata'>
|
||||
<doc:doc>
|
||||
<doc:description>
|
||||
<doc:para>
|
||||
Adds AppStream resource information from a session client.
|
||||
</doc:para>
|
||||
</doc:description>
|
||||
</doc:doc>
|
||||
<arg type='h' name='data' direction='in'>
|
||||
<doc:doc>
|
||||
<doc:summary>
|
||||
<doc:para>
|
||||
File handle to AppStream metadata.
|
||||
</doc:para>
|
||||
</doc:summary>
|
||||
</doc:doc>
|
||||
</arg>
|
||||
<arg type='h' name='signature' direction='in'>
|
||||
<doc:doc>
|
||||
<doc:summary>
|
||||
<doc:para>
|
||||
File handle to AppStream metadata GPG signature.
|
||||
</doc:para>
|
||||
</doc:summary>
|
||||
</doc:doc>
|
||||
</arg>
|
||||
</method>
|
||||
|
||||
<!--***********************************************************-->
|
||||
<signal name='Changed'>
|
||||
<doc:doc>
|
||||
|
Loading…
Reference in New Issue
Block a user