mirror of
https://git.proxmox.com/git/fwupd
synced 2025-08-08 14:36:33 +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
|
%{_libexecdir}/fwupd
|
||||||
%{_bindir}/fwupdmgr
|
%{_bindir}/fwupdmgr
|
||||||
%{_sysconfdir}/pki/fwupd
|
%{_sysconfdir}/pki/fwupd
|
||||||
|
%{_sysconfdir}/pki/fwupd-metadata
|
||||||
%{_sysconfdir}/dbus-1/system.d/org.freedesktop.fwupd.conf
|
%{_sysconfdir}/dbus-1/system.d/org.freedesktop.fwupd.conf
|
||||||
%{_datadir}/dbus-1/interfaces/org.freedesktop.fwupd.xml
|
%{_datadir}/dbus-1/interfaces/org.freedesktop.fwupd.xml
|
||||||
%{_datadir}/polkit-1/actions/org.freedesktop.fwupd.policy
|
%{_datadir}/polkit-1/actions/org.freedesktop.fwupd.policy
|
||||||
@ -90,6 +91,9 @@ find %{buildroot} -name '*.la' -exec rm -f {} ';'
|
|||||||
%dir %{_localstatedir}/lib/fwupd
|
%dir %{_localstatedir}/lib/fwupd
|
||||||
%{_libdir}/lib*.so.*
|
%{_libdir}/lib*.so.*
|
||||||
%{_libdir}/girepository-1.0/*.typelib
|
%{_libdir}/girepository-1.0/*.typelib
|
||||||
|
%dir %{_localstatedir}/cache/app-info
|
||||||
|
%dir %{_localstatedir}/cache/app-info/icons
|
||||||
|
%dir %{_localstatedir}/cache/app-info/xmls
|
||||||
|
|
||||||
%files devel
|
%files devel
|
||||||
%{_includedir}/fwupd-1
|
%{_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
|
||||||
|
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
|
||||||
|
vEI5YQ==
|
||||||
|
=/V/G
|
||||||
|
-----END PGP PUBLIC KEY BLOCK-----
|
@ -1,4 +1,7 @@
|
|||||||
pkidir = $(sysconfdir)/pki/fwupd
|
pkidir = $(sysconfdir)/pki/fwupd
|
||||||
dist_pki_DATA = GPG-KEY-Hughski-Limited
|
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
|
-include $(top_srcdir)/git.mk
|
||||||
|
@ -166,6 +166,8 @@ install-data-hook:
|
|||||||
if test -w $(DESTDIR)$(prefix)/; then \
|
if test -w $(DESTDIR)$(prefix)/; then \
|
||||||
mkdir -p $(DESTDIR)$(localstatedir)/lib/fwupd; \
|
mkdir -p $(DESTDIR)$(localstatedir)/lib/fwupd; \
|
||||||
chmod 0755 $(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
|
fi
|
||||||
|
|
||||||
TESTS = fu-self-test
|
TESTS = fu-self-test
|
||||||
|
@ -321,6 +321,94 @@ out:
|
|||||||
return ret;
|
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:
|
* fu_keyring_class_init:
|
||||||
**/
|
**/
|
||||||
|
@ -63,6 +63,10 @@ gboolean fu_keyring_verify_file (FuKeyring *keyring,
|
|||||||
const gchar *filename,
|
const gchar *filename,
|
||||||
const gchar *signature,
|
const gchar *signature,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
gboolean fu_keyring_verify_data (FuKeyring *keyring,
|
||||||
|
GBytes *payload,
|
||||||
|
GBytes *payload_signature,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
133
src/fu-main.c
133
src/fu-main.c
@ -26,6 +26,7 @@
|
|||||||
#include <glib/gstdio.h>
|
#include <glib/gstdio.h>
|
||||||
#include <gio/gio.h>
|
#include <gio/gio.h>
|
||||||
#include <gio/gunixfdlist.h>
|
#include <gio/gunixfdlist.h>
|
||||||
|
#include <gio/gunixinputstream.h>
|
||||||
#include <glib/gi18n.h>
|
#include <glib/gi18n.h>
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
#include <polkit/polkit.h>
|
#include <polkit/polkit.h>
|
||||||
@ -36,6 +37,7 @@
|
|||||||
#include "fu-cleanup.h"
|
#include "fu-cleanup.h"
|
||||||
#include "fu-debug.h"
|
#include "fu-debug.h"
|
||||||
#include "fu-device.h"
|
#include "fu-device.h"
|
||||||
|
#include "fu-keyring.h"
|
||||||
#include "fu-pending.h"
|
#include "fu-pending.h"
|
||||||
#include "fu-provider.h"
|
#include "fu-provider.h"
|
||||||
#include "fu-provider-usb.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";
|
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:
|
* fu_main_daemon_method_call:
|
||||||
**/
|
**/
|
||||||
@ -648,6 +745,42 @@ fu_main_daemon_method_call (GDBusConnection *connection, const gchar *sender,
|
|||||||
return;
|
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 '' */
|
/* return '' */
|
||||||
if (g_strcmp0 (method_name, "Update") == 0) {
|
if (g_strcmp0 (method_name, "Update") == 0) {
|
||||||
FuDeviceItem *item = NULL;
|
FuDeviceItem *item = NULL;
|
||||||
|
@ -776,6 +776,84 @@ fu_util_clear_results (FuUtilPrivate *priv, gchar **values, GError **error)
|
|||||||
return TRUE;
|
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:
|
* fu_util_get_results:
|
||||||
**/
|
**/
|
||||||
@ -1061,6 +1139,12 @@ main (int argc, char *argv[])
|
|||||||
/* TRANSLATORS: command description */
|
/* TRANSLATORS: command description */
|
||||||
_("Gets the results from the last update"),
|
_("Gets the results from the last update"),
|
||||||
fu_util_get_results);
|
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 */
|
/* sort by command name */
|
||||||
g_ptr_array_sort (priv->cmd_array,
|
g_ptr_array_sort (priv->cmd_array,
|
||||||
|
@ -169,6 +169,35 @@
|
|||||||
</arg>
|
</arg>
|
||||||
</method>
|
</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'>
|
<signal name='Changed'>
|
||||||
<doc:doc>
|
<doc:doc>
|
||||||
|
Loading…
Reference in New Issue
Block a user