Coverage Report

Created: 2026-06-15 06:54

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/fwupd/libfwupd/fwupd-security-attr.c
Line
Count
Source
1
/*
2
 * Copyright 2020 Richard Hughes <richard@hughsie.com>
3
 *
4
 * SPDX-License-Identifier: LGPL-2.1-or-later
5
 */
6
7
#include "config.h"
8
9
#include <gio/gio.h>
10
11
#include "fwupd-codec.h"
12
#include "fwupd-common-private.h"
13
#include "fwupd-enums-private.h"
14
#include "fwupd-error.h"
15
#include "fwupd-json-array.h"
16
#include "fwupd-security-attr-private.h"
17
#include "fwupd-variant.h"
18
19
/**
20
 * FwupdSecurityAttr:
21
 *
22
 * A Host Security ID attribute that represents something that was measured.
23
 */
24
25
static void
26
fwupd_security_attr_finalize(GObject *object);
27
28
typedef struct {
29
  gchar *appstream_id;
30
  GPtrArray *obsoletes;
31
  GPtrArray *guids;
32
  GHashTable *metadata; /* (nullable) */
33
  gchar *name;
34
  gchar *title;
35
  gchar *description;
36
  gchar *plugin;
37
  gchar *fwupd_version;
38
  gchar *url;
39
  guint64 created;
40
  FwupdSecurityAttrLevel level;
41
  FwupdSecurityAttrResult result;
42
  FwupdSecurityAttrResult result_fallback;
43
  FwupdSecurityAttrResult result_success;
44
  FwupdSecurityAttrFlags flags;
45
  gchar *bios_setting_id;
46
  gchar *bios_setting_target_value;
47
  gchar *bios_setting_current_value;
48
  gchar *kernel_current_value;
49
  gchar *kernel_target_value;
50
} FwupdSecurityAttrPrivate;
51
52
static void
53
fwupd_security_attr_codec_iface_init(FwupdCodecInterface *iface);
54
55
0
G_DEFINE_TYPE_EXTENDED(FwupdSecurityAttr,
56
0
           fwupd_security_attr,
57
0
           G_TYPE_OBJECT,
58
0
           0,
59
0
           G_ADD_PRIVATE(FwupdSecurityAttr)
60
0
         G_IMPLEMENT_INTERFACE(FWUPD_TYPE_CODEC,
61
0
             fwupd_security_attr_codec_iface_init));
62
0
63
0
#define GET_PRIVATE(o) (fwupd_security_attr_get_instance_private(o))
64
65
/**
66
 * fwupd_security_attr_flag_from_string:
67
 * @flag: (nullable): a string, e.g. `success`
68
 *
69
 * Converts a string to an enumerated flag.
70
 *
71
 * Returns: enumerated value
72
 *
73
 * Since: 1.7.1
74
 **/
75
FwupdSecurityAttrFlags
76
fwupd_security_attr_flag_from_string(const gchar *flag)
77
0
{
78
0
  if (g_strcmp0(flag, "success") == 0)
79
0
    return FWUPD_SECURITY_ATTR_FLAG_SUCCESS;
80
0
  if (g_strcmp0(flag, "obsoleted") == 0)
81
0
    return FWUPD_SECURITY_ATTR_FLAG_OBSOLETED;
82
0
  if (g_strcmp0(flag, "missing-data") == 0)
83
0
    return FWUPD_SECURITY_ATTR_FLAG_MISSING_DATA;
84
0
  if (g_strcmp0(flag, "runtime-updates") == 0)
85
0
    return FWUPD_SECURITY_ATTR_FLAG_RUNTIME_UPDATES;
86
0
  if (g_strcmp0(flag, "runtime-attestation") == 0)
87
0
    return FWUPD_SECURITY_ATTR_FLAG_RUNTIME_ATTESTATION;
88
0
  if (g_strcmp0(flag, "runtime-issue") == 0)
89
0
    return FWUPD_SECURITY_ATTR_FLAG_RUNTIME_ISSUE;
90
0
  if (g_strcmp0(flag, "action-contact-oem") == 0)
91
0
    return FWUPD_SECURITY_ATTR_FLAG_ACTION_CONTACT_OEM;
92
0
  if (g_strcmp0(flag, "action-config-fw") == 0)
93
0
    return FWUPD_SECURITY_ATTR_FLAG_ACTION_CONFIG_FW;
94
0
  if (g_strcmp0(flag, "action-config-os") == 0)
95
0
    return FWUPD_SECURITY_ATTR_FLAG_ACTION_CONFIG_OS;
96
0
  if (g_strcmp0(flag, "can-fix") == 0)
97
0
    return FWUPD_SECURITY_ATTR_FLAG_CAN_FIX;
98
0
  if (g_strcmp0(flag, "can-undo") == 0)
99
0
    return FWUPD_SECURITY_ATTR_FLAG_CAN_UNDO;
100
0
  return FWUPD_SECURITY_ATTR_FLAG_NONE;
101
0
}
102
103
/**
104
 * fwupd_security_attr_result_from_string:
105
 * @result: (nullable): a string, e.g. `not-encrypted`
106
 *
107
 * Converts a string to an enumerated result.
108
 *
109
 * Returns: enumerated value
110
 *
111
 * Since: 1.7.1
112
 **/
113
FwupdSecurityAttrResult
114
fwupd_security_attr_result_from_string(const gchar *result)
115
0
{
116
0
  if (g_strcmp0(result, "valid") == 0)
117
0
    return FWUPD_SECURITY_ATTR_RESULT_VALID;
118
0
  if (g_strcmp0(result, "not-valid") == 0)
119
0
    return FWUPD_SECURITY_ATTR_RESULT_NOT_VALID;
120
0
  if (g_strcmp0(result, "enabled") == 0)
121
0
    return FWUPD_SECURITY_ATTR_RESULT_ENABLED;
122
0
  if (g_strcmp0(result, "not-enabled") == 0)
123
0
    return FWUPD_SECURITY_ATTR_RESULT_NOT_ENABLED;
124
0
  if (g_strcmp0(result, "locked") == 0)
125
0
    return FWUPD_SECURITY_ATTR_RESULT_LOCKED;
126
0
  if (g_strcmp0(result, "not-locked") == 0)
127
0
    return FWUPD_SECURITY_ATTR_RESULT_NOT_LOCKED;
128
0
  if (g_strcmp0(result, "encrypted") == 0)
129
0
    return FWUPD_SECURITY_ATTR_RESULT_ENCRYPTED;
130
0
  if (g_strcmp0(result, "not-encrypted") == 0)
131
0
    return FWUPD_SECURITY_ATTR_RESULT_NOT_ENCRYPTED;
132
0
  if (g_strcmp0(result, "tainted") == 0)
133
0
    return FWUPD_SECURITY_ATTR_RESULT_TAINTED;
134
0
  if (g_strcmp0(result, "not-tainted") == 0)
135
0
    return FWUPD_SECURITY_ATTR_RESULT_NOT_TAINTED;
136
0
  if (g_strcmp0(result, "found") == 0)
137
0
    return FWUPD_SECURITY_ATTR_RESULT_FOUND;
138
0
  if (g_strcmp0(result, "not-found") == 0)
139
0
    return FWUPD_SECURITY_ATTR_RESULT_NOT_FOUND;
140
0
  if (g_strcmp0(result, "supported") == 0)
141
0
    return FWUPD_SECURITY_ATTR_RESULT_SUPPORTED;
142
0
  if (g_strcmp0(result, "not-supported") == 0)
143
0
    return FWUPD_SECURITY_ATTR_RESULT_NOT_SUPPORTED;
144
0
  return FWUPD_SECURITY_ATTR_RESULT_UNKNOWN;
145
0
}
146
147
/**
148
 * fwupd_security_attr_flag_to_suffix:
149
 * @flag: security attribute flags, e.g. %FWUPD_SECURITY_ATTR_FLAG_RUNTIME_UPDATES
150
 *
151
 * Returns the string suffix for the flag.
152
 *
153
 * Returns: string, or %NULL
154
 *
155
 * Since: 1.5.0
156
 **/
157
const gchar *
158
fwupd_security_attr_flag_to_suffix(FwupdSecurityAttrFlags flag)
159
0
{
160
0
  if (flag == FWUPD_SECURITY_ATTR_FLAG_RUNTIME_UPDATES)
161
0
    return "U";
162
0
  if (flag == FWUPD_SECURITY_ATTR_FLAG_RUNTIME_ATTESTATION)
163
0
    return "A";
164
0
  if (flag == FWUPD_SECURITY_ATTR_FLAG_RUNTIME_ISSUE)
165
0
    return "!";
166
0
  return NULL;
167
0
}
168
169
/**
170
 * fwupd_security_attr_get_bios_setting_id:
171
 * @self: a #FwupdSecurityAttr
172
 *
173
 * Gets the #FwupdBiosSetting that can be used to improve this
174
 * #FwupdSecurityAttr.
175
 *
176
 * Returns: The unique ID used for #FwupdBiosSetting or NULL
177
 *
178
 * Since: 1.8.4
179
 **/
180
const gchar *
181
fwupd_security_attr_get_bios_setting_id(FwupdSecurityAttr *self)
182
0
{
183
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
184
0
  g_return_val_if_fail(FWUPD_IS_SECURITY_ATTR(self), NULL);
185
0
  return priv->bios_setting_id;
186
0
}
187
188
/**
189
 * fwupd_security_attr_set_bios_setting_id:
190
 * @self: a #FwupdSecurityAttr
191
 * @id: (nullable): Unique identifier used for #FwupdBiosSetting
192
 *
193
 * Sets the #FwupdBiosSetting that can be used to improve this
194
 * #FwupdSecurityAttr.
195
 *
196
 * Since: 1.8.4
197
 **/
198
void
199
fwupd_security_attr_set_bios_setting_id(FwupdSecurityAttr *self, const gchar *id)
200
0
{
201
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
202
0
  g_return_if_fail(FWUPD_IS_SECURITY_ATTR(self));
203
0
  if (priv->bios_setting_id == id)
204
0
    return;
205
0
  g_free(priv->bios_setting_id);
206
0
  priv->bios_setting_id = g_strdup(id);
207
0
}
208
209
/**
210
 * fwupd_security_attr_get_obsoletes:
211
 * @self: a #FwupdSecurityAttr
212
 *
213
 * Gets the list of attribute obsoletes. The obsoleted attributes will not
214
 * contribute to the calculated HSI value or be visible in command line tools.
215
 *
216
 * Returns: (element-type utf8) (transfer none): the obsoletes, which may be empty
217
 *
218
 * Since: 1.5.0
219
 **/
220
GPtrArray *
221
fwupd_security_attr_get_obsoletes(FwupdSecurityAttr *self)
222
0
{
223
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
224
0
  g_return_val_if_fail(FWUPD_IS_SECURITY_ATTR(self), NULL);
225
0
  return priv->obsoletes;
226
0
}
227
228
/**
229
 * fwupd_security_attr_add_obsolete:
230
 * @self: a #FwupdSecurityAttr
231
 * @appstream_id: the appstream_id or plugin name
232
 *
233
 * Adds an attribute appstream_id to obsolete. The obsoleted attribute will not
234
 * contribute to the calculated HSI value or be visible in command line tools.
235
 *
236
 * Since: 1.5.0
237
 **/
238
void
239
fwupd_security_attr_add_obsolete(FwupdSecurityAttr *self, const gchar *appstream_id)
240
0
{
241
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
242
0
  g_return_if_fail(FWUPD_IS_SECURITY_ATTR(self));
243
0
  g_return_if_fail(appstream_id != NULL);
244
0
  if (fwupd_security_attr_has_obsolete(self, appstream_id))
245
0
    return;
246
0
  g_ptr_array_add(priv->obsoletes, g_strdup(appstream_id));
247
0
}
248
249
/**
250
 * fwupd_security_attr_has_obsolete:
251
 * @self: a #FwupdSecurityAttr
252
 * @appstream_id: the attribute appstream_id
253
 *
254
 * Finds out if the attribute obsoletes a specific appstream_id.
255
 *
256
 * Returns: %TRUE if the self matches
257
 *
258
 * Since: 1.5.0
259
 **/
260
gboolean
261
fwupd_security_attr_has_obsolete(FwupdSecurityAttr *self, const gchar *appstream_id)
262
0
{
263
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
264
0
  g_return_val_if_fail(FWUPD_IS_SECURITY_ATTR(self), FALSE);
265
0
  g_return_val_if_fail(appstream_id != NULL, FALSE);
266
0
  for (guint i = 0; i < priv->obsoletes->len; i++) {
267
0
    const gchar *obsolete_tmp = g_ptr_array_index(priv->obsoletes, i);
268
0
    if (g_strcmp0(obsolete_tmp, appstream_id) == 0)
269
0
      return TRUE;
270
0
  }
271
0
  return FALSE;
272
0
}
273
274
/**
275
 * fwupd_security_attr_get_guids:
276
 * @self: a #FwupdSecurityAttr
277
 *
278
 * Gets the list of attribute GUIDs. The GUID values will not modify the calculated HSI value.
279
 *
280
 * Returns: (element-type utf8) (transfer none): the GUIDs, which may be empty
281
 *
282
 * Since: 1.7.0
283
 **/
284
GPtrArray *
285
fwupd_security_attr_get_guids(FwupdSecurityAttr *self)
286
0
{
287
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
288
0
  g_return_val_if_fail(FWUPD_IS_SECURITY_ATTR(self), NULL);
289
0
  return priv->guids;
290
0
}
291
292
/**
293
 * fwupd_security_attr_add_guid:
294
 * @self: a #FwupdSecurityAttr
295
 * @guid: (not nullable): the GUID
296
 *
297
 * Adds a device GUID to the attribute. This indicates the GUID in some way contributed to the
298
 * result decided.
299
 *
300
 * Since: 1.7.0
301
 **/
302
void
303
fwupd_security_attr_add_guid(FwupdSecurityAttr *self, const gchar *guid)
304
0
{
305
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
306
0
  g_return_if_fail(FWUPD_IS_SECURITY_ATTR(self));
307
0
  g_return_if_fail(fwupd_guid_is_valid(guid));
308
0
  if (fwupd_security_attr_has_guid(self, guid))
309
0
    return;
310
0
  g_ptr_array_add(priv->guids, g_strdup(guid));
311
0
}
312
313
/**
314
 * fwupd_security_attr_add_guids:
315
 * @self: a #FwupdSecurityAttr
316
 * @guids: (element-type utf8): the GUIDs
317
 *
318
 * Adds device GUIDs to the attribute. This indicates the GUIDs in some way contributed to the
319
 * result decided.
320
 *
321
 * Since: 1.7.0
322
 **/
323
void
324
fwupd_security_attr_add_guids(FwupdSecurityAttr *self, GPtrArray *guids)
325
0
{
326
0
  g_return_if_fail(FWUPD_IS_SECURITY_ATTR(self));
327
0
  g_return_if_fail(guids != NULL);
328
0
  for (guint i = 0; i < guids->len; i++) {
329
0
    const gchar *guid = g_ptr_array_index(guids, i);
330
0
    fwupd_security_attr_add_guid(self, guid);
331
0
  }
332
0
}
333
334
/**
335
 * fwupd_security_attr_has_guid:
336
 * @self: a #FwupdSecurityAttr
337
 * @guid: the attribute guid
338
 *
339
 * Finds out if a specific GUID was added to the attribute.
340
 *
341
 * Returns: %TRUE if the self matches
342
 *
343
 * Since: 1.7.0
344
 **/
345
gboolean
346
fwupd_security_attr_has_guid(FwupdSecurityAttr *self, const gchar *guid)
347
0
{
348
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
349
0
  g_return_val_if_fail(FWUPD_IS_SECURITY_ATTR(self), FALSE);
350
0
  g_return_val_if_fail(guid != NULL, FALSE);
351
0
  for (guint i = 0; i < priv->guids->len; i++) {
352
0
    const gchar *guid_tmp = g_ptr_array_index(priv->guids, i);
353
0
    if (g_strcmp0(guid_tmp, guid) == 0)
354
0
      return TRUE;
355
0
  }
356
0
  return FALSE;
357
0
}
358
359
/**
360
 * fwupd_security_attr_get_appstream_id:
361
 * @self: a #FwupdSecurityAttr
362
 *
363
 * Gets the AppStream ID.
364
 *
365
 * Returns: the AppStream ID, or %NULL if unset
366
 *
367
 * Since: 1.5.0
368
 **/
369
const gchar *
370
fwupd_security_attr_get_appstream_id(FwupdSecurityAttr *self)
371
0
{
372
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
373
0
  g_return_val_if_fail(FWUPD_IS_SECURITY_ATTR(self), NULL);
374
0
  return priv->appstream_id;
375
0
}
376
377
/**
378
 * fwupd_security_attr_set_appstream_id:
379
 * @self: a #FwupdSecurityAttr
380
 * @appstream_id: (nullable): the AppStream component ID, e.g. `com.intel.BiosGuard`
381
 *
382
 * Sets the AppStream ID.
383
 *
384
 * Since: 1.5.0
385
 **/
386
void
387
fwupd_security_attr_set_appstream_id(FwupdSecurityAttr *self, const gchar *appstream_id)
388
0
{
389
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
390
0
  g_return_if_fail(FWUPD_IS_SECURITY_ATTR(self));
391
392
  /* not changed */
393
0
  if (g_strcmp0(priv->appstream_id, appstream_id) == 0)
394
0
    return;
395
396
  /* sanity check */
397
0
  if (appstream_id != NULL && !g_str_has_prefix(appstream_id, "org.fwupd.hsi."))
398
0
    g_critical("HSI attributes need to have a 'org.fwupd.hsi.' prefix");
399
400
0
  g_free(priv->appstream_id);
401
0
  priv->appstream_id = g_strdup(appstream_id);
402
0
}
403
404
/**
405
 * fwupd_security_attr_get_url:
406
 * @self: a #FwupdSecurityAttr
407
 *
408
 * Gets the attribute URL.
409
 *
410
 * Returns: the attribute result, or %NULL if unset
411
 *
412
 * Since: 1.5.0
413
 **/
414
const gchar *
415
fwupd_security_attr_get_url(FwupdSecurityAttr *self)
416
0
{
417
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
418
0
  g_return_val_if_fail(FWUPD_IS_SECURITY_ATTR(self), NULL);
419
0
  return priv->url;
420
0
}
421
422
/**
423
 * fwupd_security_attr_set_name:
424
 * @self: a #FwupdSecurityAttr
425
 * @name: (nullable): the attribute name
426
 *
427
 * Sets the attribute name.
428
 *
429
 * Since: 1.5.0
430
 **/
431
void
432
fwupd_security_attr_set_name(FwupdSecurityAttr *self, const gchar *name)
433
0
{
434
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
435
0
  g_return_if_fail(FWUPD_IS_SECURITY_ATTR(self));
436
437
  /* not changed */
438
0
  if (g_strcmp0(priv->name, name) == 0)
439
0
    return;
440
441
0
  g_free(priv->name);
442
0
  priv->name = g_strdup(name);
443
0
}
444
445
/**
446
 * fwupd_security_attr_get_bios_setting_target_value:
447
 * @self: a #FwupdSecurityAttr
448
 *
449
 * Gets the value that when written to an attribute would activate it or satisfy
450
 * a security requirement.
451
 *
452
 * Returns: the target value of the attribute.
453
 *
454
 * Since: 1.8.4
455
 **/
456
const gchar *
457
fwupd_security_attr_get_bios_setting_target_value(FwupdSecurityAttr *self)
458
0
{
459
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
460
0
  g_return_val_if_fail(FWUPD_IS_SECURITY_ATTR(self), NULL);
461
0
  return priv->bios_setting_target_value;
462
0
}
463
464
/**
465
 * fwupd_security_attr_set_bios_setting_target_value:
466
 * @self: a #FwupdSecurityAttr
467
 * @value: (nullable): The string to set target value to
468
 *
469
 * Sets the string used for the target value of an attribute.
470
 *
471
 * Since: 1.8.4
472
 **/
473
void
474
fwupd_security_attr_set_bios_setting_target_value(FwupdSecurityAttr *self, const gchar *value)
475
0
{
476
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
477
478
  /* not changed */
479
0
  if (g_strcmp0(priv->bios_setting_target_value, value) == 0)
480
0
    return;
481
482
0
  g_free(priv->bios_setting_target_value);
483
0
  priv->bios_setting_target_value = g_strdup(value);
484
0
}
485
486
/**
487
 * fwupd_security_attr_get_bios_setting_current_value:
488
 * @self: a #FwupdSecurityAttr
489
 *
490
 * Gets the current value of the BIOS setting that can be changed.
491
 *
492
 * Returns: the current value of the attribute.
493
 *
494
 * Since: 1.8.4
495
 **/
496
const gchar *
497
fwupd_security_attr_get_bios_setting_current_value(FwupdSecurityAttr *self)
498
0
{
499
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
500
0
  g_return_val_if_fail(FWUPD_IS_SECURITY_ATTR(self), NULL);
501
0
  return priv->bios_setting_current_value;
502
0
}
503
504
/**
505
 * fwupd_security_attr_set_bios_setting_current_value:
506
 * @self: a #FwupdSecurityAttr
507
 * @value: (nullable): The string to set current value to
508
 *
509
 * Sets the current value of the BIOS setting that can be changed.
510
 *
511
 * Since: 1.8.4
512
 **/
513
void
514
fwupd_security_attr_set_bios_setting_current_value(FwupdSecurityAttr *self, const gchar *value)
515
0
{
516
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
517
518
  /* not changed */
519
0
  if (g_strcmp0(priv->bios_setting_current_value, value) == 0)
520
0
    return;
521
522
0
  g_free(priv->bios_setting_current_value);
523
0
  priv->bios_setting_current_value = g_strdup(value);
524
0
}
525
526
/**
527
 * fwupd_security_attr_get_kernel_current_value:
528
 * @self: a #FwupdSecurityAttr
529
 *
530
 * Gets the current value of the BIOS setting that can be changed.
531
 *
532
 * Returns: the current value of the attribute.
533
 *
534
 * Since: 1.9.6
535
 **/
536
const gchar *
537
fwupd_security_attr_get_kernel_current_value(FwupdSecurityAttr *self)
538
0
{
539
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
540
0
  g_return_val_if_fail(FWUPD_IS_SECURITY_ATTR(self), NULL);
541
0
  return priv->kernel_current_value;
542
0
}
543
544
/**
545
 * fwupd_security_attr_set_kernel_current_value:
546
 * @self: a #FwupdSecurityAttr
547
 * @value: (nullable): The string to set current value to
548
 *
549
 * Sets the current value of the BIOS setting that can be changed.
550
 *
551
 * Since: 1.9.6
552
 **/
553
void
554
fwupd_security_attr_set_kernel_current_value(FwupdSecurityAttr *self, const gchar *value)
555
0
{
556
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
557
558
  /* not changed */
559
0
  if (g_strcmp0(priv->kernel_current_value, value) == 0)
560
0
    return;
561
562
0
  g_free(priv->kernel_current_value);
563
0
  priv->kernel_current_value = g_strdup(value);
564
0
}
565
566
/**
567
 * fwupd_security_attr_get_kernel_target_value:
568
 * @self: a #FwupdSecurityAttr
569
 *
570
 * Gets the target value of the kernel setting that can be changed.
571
 *
572
 * Returns: the current value of the attribute.
573
 *
574
 * Since: 1.9.6
575
 **/
576
const gchar *
577
fwupd_security_attr_get_kernel_target_value(FwupdSecurityAttr *self)
578
0
{
579
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
580
0
  g_return_val_if_fail(FWUPD_IS_SECURITY_ATTR(self), NULL);
581
0
  return priv->kernel_target_value;
582
0
}
583
584
/**
585
 * fwupd_security_attr_set_kernel_target_value:
586
 * @self: a #FwupdSecurityAttr
587
 * @value: (nullable): The string to set current value to
588
 *
589
 * Sets the target value of the kernel setting that can be changed.
590
 *
591
 * Since: 1.9.6
592
 **/
593
void
594
fwupd_security_attr_set_kernel_target_value(FwupdSecurityAttr *self, const gchar *value)
595
0
{
596
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
597
598
  /* not changed */
599
0
  if (g_strcmp0(priv->kernel_target_value, value) == 0)
600
0
    return;
601
602
0
  g_free(priv->kernel_target_value);
603
0
  priv->kernel_target_value = g_strdup(value);
604
0
}
605
606
/**
607
 * fwupd_security_attr_set_title:
608
 * @self: a #FwupdSecurityAttr
609
 * @title: (nullable): the attribute title
610
 *
611
 * Sets the attribute title.
612
 *
613
 * Since: 1.8.2
614
 **/
615
void
616
fwupd_security_attr_set_title(FwupdSecurityAttr *self, const gchar *title)
617
0
{
618
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
619
0
  g_return_if_fail(FWUPD_IS_SECURITY_ATTR(self));
620
621
  /* not changed */
622
0
  if (g_strcmp0(priv->title, title) == 0)
623
0
    return;
624
625
0
  g_free(priv->title);
626
0
  priv->title = g_strdup(title);
627
0
}
628
629
/**
630
 * fwupd_security_attr_set_description:
631
 * @self: a #FwupdSecurityAttr
632
 * @description: (nullable): the attribute description
633
 *
634
 * Sets the attribute description.
635
 *
636
 * Since: 1.8.2
637
 **/
638
void
639
fwupd_security_attr_set_description(FwupdSecurityAttr *self, const gchar *description)
640
0
{
641
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
642
0
  g_return_if_fail(FWUPD_IS_SECURITY_ATTR(self));
643
644
  /* not changed */
645
0
  if (g_strcmp0(priv->description, description) == 0)
646
0
    return;
647
648
0
  g_free(priv->description);
649
0
  priv->description = g_strdup(description);
650
0
}
651
652
/**
653
 * fwupd_security_attr_set_plugin:
654
 * @self: a #FwupdSecurityAttr
655
 * @plugin: (nullable): the plugin name
656
 *
657
 * Sets the plugin that created the attribute.
658
 *
659
 * Since: 1.5.0
660
 **/
661
void
662
fwupd_security_attr_set_plugin(FwupdSecurityAttr *self, const gchar *plugin)
663
0
{
664
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
665
0
  g_return_if_fail(FWUPD_IS_SECURITY_ATTR(self));
666
667
  /* not changed */
668
0
  if (g_strcmp0(priv->plugin, plugin) == 0)
669
0
    return;
670
671
0
  g_free(priv->plugin);
672
0
  priv->plugin = g_strdup(plugin);
673
0
}
674
675
/**
676
 * fwupd_security_attr_set_fwupd_version:
677
 * @self: a #FwupdSecurityAttr
678
 * @fwupd_version: (nullable): the fwupd version, e.g. `2.0.7`
679
 *
680
 * Sets the fwupd version the attribute was added.
681
 *
682
 * Since: 2.0.7
683
 **/
684
void
685
fwupd_security_attr_set_fwupd_version(FwupdSecurityAttr *self, const gchar *fwupd_version)
686
0
{
687
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
688
0
  g_return_if_fail(FWUPD_IS_SECURITY_ATTR(self));
689
690
  /* not changed */
691
0
  if (g_strcmp0(priv->fwupd_version, fwupd_version) == 0)
692
0
    return;
693
694
0
  g_free(priv->fwupd_version);
695
0
  priv->fwupd_version = g_strdup(fwupd_version);
696
0
}
697
698
/**
699
 * fwupd_security_attr_set_url:
700
 * @self: a #FwupdSecurityAttr
701
 * @url: (nullable): the attribute URL
702
 *
703
 * Sets the attribute result.
704
 *
705
 * Since: 1.5.0
706
 **/
707
void
708
fwupd_security_attr_set_url(FwupdSecurityAttr *self, const gchar *url)
709
0
{
710
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
711
0
  g_return_if_fail(FWUPD_IS_SECURITY_ATTR(self));
712
713
  /* not changed */
714
0
  if (g_strcmp0(priv->url, url) == 0)
715
0
    return;
716
717
0
  g_free(priv->url);
718
0
  priv->url = g_strdup(url);
719
0
}
720
/**
721
 * fwupd_security_attr_get_created:
722
 * @self: a #FwupdSecurityAttr
723
 *
724
 * Gets when the attribute was created.
725
 *
726
 * Returns: the UNIX time, or 0 if unset
727
 *
728
 * Since: 1.7.1
729
 **/
730
guint64
731
fwupd_security_attr_get_created(FwupdSecurityAttr *self)
732
0
{
733
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
734
0
  g_return_val_if_fail(FWUPD_IS_SECURITY_ATTR(self), 0);
735
0
  return priv->created;
736
0
}
737
738
/**
739
 * fwupd_security_attr_set_created:
740
 * @self: a #FwupdSecurityAttr
741
 * @created: the UNIX time
742
 *
743
 * Sets when the attribute was created.
744
 *
745
 * Since: 1.7.1
746
 **/
747
void
748
fwupd_security_attr_set_created(FwupdSecurityAttr *self, guint64 created)
749
0
{
750
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
751
0
  g_return_if_fail(FWUPD_IS_SECURITY_ATTR(self));
752
0
  priv->created = created;
753
0
}
754
755
/**
756
 * fwupd_security_attr_get_name:
757
 * @self: a #FwupdSecurityAttr
758
 *
759
 * Gets the attribute name.
760
 *
761
 * Returns: the attribute name, or %NULL if unset
762
 *
763
 * Since: 1.5.0
764
 **/
765
const gchar *
766
fwupd_security_attr_get_name(FwupdSecurityAttr *self)
767
0
{
768
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
769
0
  g_return_val_if_fail(FWUPD_IS_SECURITY_ATTR(self), NULL);
770
0
  return priv->name;
771
0
}
772
773
/**
774
 * fwupd_security_attr_get_title:
775
 * @self: a #FwupdSecurityAttr
776
 *
777
 * Gets the attribute title, which is typically a two word title.
778
 *
779
 * The fwupd client program may be able to get translations for this value using a method call
780
 * like `dgettext("fwupd",str)`.
781
 *
782
 * Returns: the attribute title, or %NULL if unset
783
 *
784
 * Since: 1.8.2
785
 **/
786
const gchar *
787
fwupd_security_attr_get_title(FwupdSecurityAttr *self)
788
0
{
789
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
790
0
  g_return_val_if_fail(FWUPD_IS_SECURITY_ATTR(self), NULL);
791
0
  return priv->title;
792
0
}
793
794
/**
795
 * fwupd_security_attr_get_description:
796
 * @self: a #FwupdSecurityAttr
797
 *
798
 * Gets the attribute description which is a few lines of prose that normal users will understand.
799
 *
800
 * The fwupd client program may be able to get translations for this value using a method call
801
 * like `dgettext("fwupd",str)`.
802
 *
803
 * NOTE: The returned string may contain placeholders such as `$HostVendor$` or `$HostProduct$`
804
 * and these should be replaced with the values from [method@FwupdClient.get_host_vendor] and
805
 * [method@FwupdClient.get_host_product].
806
 *
807
 * Returns: the attribute description, or %NULL if unset
808
 *
809
 * Since: 1.8.2
810
 **/
811
const gchar *
812
fwupd_security_attr_get_description(FwupdSecurityAttr *self)
813
0
{
814
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
815
0
  g_return_val_if_fail(FWUPD_IS_SECURITY_ATTR(self), NULL);
816
0
  return priv->description;
817
0
}
818
819
/**
820
 * fwupd_security_attr_get_plugin:
821
 * @self: a #FwupdSecurityAttr
822
 *
823
 * Gets the plugin that created the attribute.
824
 *
825
 * Returns: the plugin name, or %NULL if unset
826
 *
827
 * Since: 1.5.0
828
 **/
829
const gchar *
830
fwupd_security_attr_get_plugin(FwupdSecurityAttr *self)
831
0
{
832
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
833
0
  g_return_val_if_fail(FWUPD_IS_SECURITY_ATTR(self), NULL);
834
0
  return priv->plugin;
835
0
}
836
837
/**
838
 * fwupd_security_attr_get_fwupd_version:
839
 * @self: a #FwupdSecurityAttr
840
 *
841
 * Gets the fwupd version the attribute was added.
842
 *
843
 * Returns: the fwupd version, or %NULL if unset
844
 *
845
 * Since: 2.0.7
846
 **/
847
const gchar *
848
fwupd_security_attr_get_fwupd_version(FwupdSecurityAttr *self)
849
0
{
850
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
851
0
  g_return_val_if_fail(FWUPD_IS_SECURITY_ATTR(self), NULL);
852
0
  return priv->fwupd_version;
853
0
}
854
855
/**
856
 * fwupd_security_attr_get_flags:
857
 * @self: a #FwupdSecurityAttr
858
 *
859
 * Gets the self flags.
860
 *
861
 * Returns: security attribute flags, or 0 if unset
862
 *
863
 * Since: 1.5.0
864
 **/
865
FwupdSecurityAttrFlags
866
fwupd_security_attr_get_flags(FwupdSecurityAttr *self)
867
0
{
868
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
869
0
  g_return_val_if_fail(FWUPD_IS_SECURITY_ATTR(self), 0);
870
0
  return priv->flags;
871
0
}
872
873
/**
874
 * fwupd_security_attr_set_flags:
875
 * @self: a #FwupdSecurityAttr
876
 * @flags: security attribute flags, e.g. %FWUPD_SECURITY_ATTR_FLAG_OBSOLETED
877
 *
878
 * Sets the attribute flags.
879
 *
880
 * Since: 1.5.0
881
 **/
882
void
883
fwupd_security_attr_set_flags(FwupdSecurityAttr *self, FwupdSecurityAttrFlags flags)
884
0
{
885
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
886
0
  g_return_if_fail(FWUPD_IS_SECURITY_ATTR(self));
887
0
  priv->flags = flags;
888
0
}
889
890
/* copy over the success result if not already set */
891
static void
892
fwupd_security_attr_ensure_result(FwupdSecurityAttr *self)
893
0
{
894
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
895
0
  if (!fwupd_security_attr_has_flag(self, FWUPD_SECURITY_ATTR_FLAG_SUCCESS))
896
0
    return;
897
0
  if (fwupd_security_attr_has_flag(self, FWUPD_SECURITY_ATTR_FLAG_MISSING_DATA))
898
0
    fwupd_security_attr_remove_flag(self, FWUPD_SECURITY_ATTR_FLAG_MISSING_DATA);
899
0
  if (priv->result == FWUPD_SECURITY_ATTR_RESULT_UNKNOWN &&
900
0
      priv->result_success != FWUPD_SECURITY_ATTR_RESULT_UNKNOWN) {
901
0
    g_debug("auto-setting %s result %s",
902
0
      priv->appstream_id,
903
0
      fwupd_security_attr_result_to_string(priv->result_success));
904
0
    priv->result = priv->result_success;
905
0
  }
906
0
}
907
908
/**
909
 * fwupd_security_attr_add_flag:
910
 * @self: a #FwupdSecurityAttr
911
 * @flag: the #FwupdSecurityAttrFlags, e.g. %FWUPD_SECURITY_ATTR_FLAG_OBSOLETED
912
 *
913
 * Adds a specific attribute flag to the attribute.
914
 *
915
 * Since: 1.5.0
916
 **/
917
void
918
fwupd_security_attr_add_flag(FwupdSecurityAttr *self, FwupdSecurityAttrFlags flag)
919
0
{
920
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
921
0
  g_return_if_fail(FWUPD_IS_SECURITY_ATTR(self));
922
0
  priv->flags |= flag;
923
0
  fwupd_security_attr_ensure_result(self);
924
0
}
925
926
/**
927
 * fwupd_security_attr_remove_flag:
928
 * @self: a #FwupdSecurityAttr
929
 * @flag: the #FwupdSecurityAttrFlags, e.g. %FWUPD_SECURITY_ATTR_FLAG_OBSOLETED
930
 *
931
 * Removes a specific attribute flag from the attribute.
932
 *
933
 * Since: 1.8.3
934
 **/
935
void
936
fwupd_security_attr_remove_flag(FwupdSecurityAttr *self, FwupdSecurityAttrFlags flag)
937
0
{
938
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
939
0
  g_return_if_fail(FWUPD_IS_SECURITY_ATTR(self));
940
0
  priv->flags &= ~flag;
941
0
}
942
943
/**
944
 * fwupd_security_attr_has_flag:
945
 * @self: a #FwupdSecurityAttr
946
 * @flag: the attribute flag, e.g. %FWUPD_SECURITY_ATTR_FLAG_OBSOLETED
947
 *
948
 * Finds if the attribute has a specific attribute flag.
949
 *
950
 * Returns: %TRUE if the flag is set
951
 *
952
 * Since: 1.5.0
953
 **/
954
gboolean
955
fwupd_security_attr_has_flag(FwupdSecurityAttr *self, FwupdSecurityAttrFlags flag)
956
0
{
957
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
958
0
  g_return_val_if_fail(FWUPD_IS_SECURITY_ATTR(self), FALSE);
959
0
  return (priv->flags & flag) > 0;
960
0
}
961
962
/**
963
 * fwupd_security_attr_get_level:
964
 * @self: a #FwupdSecurityAttr
965
 *
966
 * Gets the HSI level.
967
 *
968
 * Returns: the security attribute level, or %FWUPD_SECURITY_ATTR_LEVEL_NONE if unset
969
 *
970
 * Since: 1.5.0
971
 **/
972
FwupdSecurityAttrLevel
973
fwupd_security_attr_get_level(FwupdSecurityAttr *self)
974
0
{
975
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
976
0
  g_return_val_if_fail(FWUPD_IS_SECURITY_ATTR(self), 0);
977
0
  return priv->level;
978
0
}
979
980
/**
981
 * fwupd_security_attr_set_level:
982
 * @self: a #FwupdSecurityAttr
983
 * @level: a security attribute level, e.g. %FWUPD_SECURITY_ATTR_LEVEL_IMPORTANT
984
 *
985
 * Sets the HSI level. A @level of %FWUPD_SECURITY_ATTR_LEVEL_NONE is not used
986
 * for the HSI calculation.
987
 *
988
 * Since: 1.5.0
989
 **/
990
void
991
fwupd_security_attr_set_level(FwupdSecurityAttr *self, FwupdSecurityAttrLevel level)
992
0
{
993
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
994
0
  g_return_if_fail(FWUPD_IS_SECURITY_ATTR(self));
995
0
  priv->level = level;
996
0
}
997
998
/**
999
 * fwupd_security_attr_set_result:
1000
 * @self: a #FwupdSecurityAttr
1001
 * @result: a security attribute result, e.g. %FWUPD_SECURITY_ATTR_LEVEL_LOCKED
1002
 *
1003
 * Sets the optional HSI result. This is required because some attributes may
1004
 * be a "success" when something is `locked` or may be "failed" if `found`.
1005
 *
1006
 * Since: 1.5.0
1007
 **/
1008
void
1009
fwupd_security_attr_set_result(FwupdSecurityAttr *self, FwupdSecurityAttrResult result)
1010
0
{
1011
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
1012
0
  g_return_if_fail(FWUPD_IS_SECURITY_ATTR(self));
1013
1014
  /* fixup any legacy attributes to the 'modern' value */
1015
0
  if (g_strcmp0(priv->appstream_id, FWUPD_SECURITY_ATTR_ID_ENCRYPTED_RAM) == 0 &&
1016
0
      result == FWUPD_SECURITY_ATTR_RESULT_NOT_ENCRYPTED) {
1017
0
    result = FWUPD_SECURITY_ATTR_RESULT_NOT_SUPPORTED;
1018
0
  }
1019
1020
0
  priv->result = result;
1021
0
}
1022
1023
/**
1024
 * fwupd_security_attr_get_result:
1025
 * @self: a #FwupdSecurityAttr
1026
 *
1027
 * Gets the optional HSI result.
1028
 *
1029
 * Returns: the #FwupdSecurityAttrResult, e.g %FWUPD_SECURITY_ATTR_LEVEL_LOCKED
1030
 *
1031
 * Since: 1.5.0
1032
 **/
1033
FwupdSecurityAttrResult
1034
fwupd_security_attr_get_result(FwupdSecurityAttr *self)
1035
0
{
1036
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
1037
0
  g_return_val_if_fail(FWUPD_IS_SECURITY_ATTR(self), 0);
1038
0
  return priv->result;
1039
0
}
1040
1041
/**
1042
 * fwupd_security_attr_set_result_fallback:
1043
 * @self: a #FwupdSecurityAttr
1044
 * @result: a security attribute, e.g. %FWUPD_SECURITY_ATTR_LEVEL_LOCKED
1045
 *
1046
 * Sets the optional fallback HSI result. The fallback may represent the old state, or a state
1047
 * that may be considered equivalent.
1048
 *
1049
 * Since: 1.7.1
1050
 **/
1051
void
1052
fwupd_security_attr_set_result_fallback(FwupdSecurityAttr *self, FwupdSecurityAttrResult result)
1053
0
{
1054
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
1055
0
  g_return_if_fail(FWUPD_IS_SECURITY_ATTR(self));
1056
0
  priv->result_fallback = result;
1057
0
}
1058
1059
/**
1060
 * fwupd_security_attr_get_result_fallback:
1061
 * @self: a #FwupdSecurityAttr
1062
 *
1063
 * Gets the optional fallback HSI result.
1064
 *
1065
 * Returns: the #FwupdSecurityAttrResult, e.g %FWUPD_SECURITY_ATTR_LEVEL_LOCKED
1066
 *
1067
 * Since: 1.7.1
1068
 **/
1069
FwupdSecurityAttrResult
1070
fwupd_security_attr_get_result_fallback(FwupdSecurityAttr *self)
1071
0
{
1072
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
1073
0
  g_return_val_if_fail(FWUPD_IS_SECURITY_ATTR(self), 0);
1074
0
  return priv->result_fallback;
1075
0
}
1076
1077
/**
1078
 * fwupd_security_attr_set_result_success:
1079
 * @self: a #FwupdSecurityAttr
1080
 * @result: a security attribute, e.g. %FWUPD_SECURITY_ATTR_LEVEL_LOCKED
1081
 *
1082
 * Sets the desired HSI result.
1083
 *
1084
 * Since: 1.9.3
1085
 **/
1086
void
1087
fwupd_security_attr_set_result_success(FwupdSecurityAttr *self, FwupdSecurityAttrResult result)
1088
0
{
1089
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
1090
0
  g_return_if_fail(FWUPD_IS_SECURITY_ATTR(self));
1091
0
  priv->result_success = result;
1092
0
  fwupd_security_attr_ensure_result(self);
1093
0
}
1094
1095
/**
1096
 * fwupd_security_attr_get_result_success:
1097
 * @self: a #FwupdSecurityAttr
1098
 *
1099
 * Gets the desired HSI result.
1100
 *
1101
 * Returns: the #FwupdSecurityAttrResult, e.g %FWUPD_SECURITY_ATTR_LEVEL_LOCKED
1102
 *
1103
 * Since: 1.9.3
1104
 **/
1105
FwupdSecurityAttrResult
1106
fwupd_security_attr_get_result_success(FwupdSecurityAttr *self)
1107
0
{
1108
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
1109
0
  g_return_val_if_fail(FWUPD_IS_SECURITY_ATTR(self), 0);
1110
0
  return priv->result_success;
1111
0
}
1112
1113
static void
1114
fwupd_security_attr_add_variant(FwupdCodec *codec, GVariantBuilder *builder, FwupdCodecFlags flags)
1115
0
{
1116
0
  FwupdSecurityAttr *self = FWUPD_SECURITY_ATTR(codec);
1117
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
1118
1119
0
  if (priv->appstream_id != NULL) {
1120
0
    g_variant_builder_add(builder,
1121
0
              "{sv}",
1122
0
              FWUPD_RESULT_KEY_APPSTREAM_ID,
1123
0
              g_variant_new_string(priv->appstream_id));
1124
0
  }
1125
0
  if (priv->created > 0) {
1126
0
    g_variant_builder_add(builder,
1127
0
              "{sv}",
1128
0
              FWUPD_RESULT_KEY_CREATED,
1129
0
              g_variant_new_uint64(priv->created));
1130
0
  }
1131
0
  if (priv->name != NULL) {
1132
0
    g_variant_builder_add(builder,
1133
0
              "{sv}",
1134
0
              FWUPD_RESULT_KEY_NAME,
1135
0
              g_variant_new_string(priv->name));
1136
0
  }
1137
0
  if (priv->title != NULL) {
1138
0
    g_variant_builder_add(builder,
1139
0
              "{sv}",
1140
0
              FWUPD_RESULT_KEY_SUMMARY,
1141
0
              g_variant_new_string(priv->title));
1142
0
  }
1143
0
  if (priv->description != NULL) {
1144
0
    g_variant_builder_add(builder,
1145
0
              "{sv}",
1146
0
              FWUPD_RESULT_KEY_DESCRIPTION,
1147
0
              g_variant_new_string(priv->description));
1148
0
  }
1149
0
  if (priv->plugin != NULL) {
1150
0
    g_variant_builder_add(builder,
1151
0
              "{sv}",
1152
0
              FWUPD_RESULT_KEY_PLUGIN,
1153
0
              g_variant_new_string(priv->plugin));
1154
0
  }
1155
0
  if (priv->fwupd_version != NULL) {
1156
0
    g_variant_builder_add(builder,
1157
0
              "{sv}",
1158
0
              FWUPD_RESULT_KEY_VERSION,
1159
0
              g_variant_new_string(priv->fwupd_version));
1160
0
  }
1161
0
  if (priv->url != NULL) {
1162
0
    g_variant_builder_add(builder,
1163
0
              "{sv}",
1164
0
              FWUPD_RESULT_KEY_URI,
1165
0
              g_variant_new_string(priv->url));
1166
0
  }
1167
0
  if (priv->obsoletes->len > 0) {
1168
0
    g_autofree const gchar **strv = g_new0(const gchar *, priv->obsoletes->len + 1);
1169
0
    for (guint i = 0; i < priv->obsoletes->len; i++)
1170
0
      strv[i] = (const gchar *)g_ptr_array_index(priv->obsoletes, i);
1171
0
    g_variant_builder_add(builder,
1172
0
              "{sv}",
1173
0
              FWUPD_RESULT_KEY_CATEGORIES,
1174
0
              g_variant_new_strv(strv, -1));
1175
0
  }
1176
0
  if (priv->guids->len > 0) {
1177
0
    g_autofree const gchar **strv = g_new0(const gchar *, priv->guids->len + 1);
1178
0
    for (guint i = 0; i < priv->guids->len; i++)
1179
0
      strv[i] = (const gchar *)g_ptr_array_index(priv->guids, i);
1180
0
    g_variant_builder_add(builder,
1181
0
              "{sv}",
1182
0
              FWUPD_RESULT_KEY_GUID,
1183
0
              g_variant_new_strv(strv, -1));
1184
0
  }
1185
0
  if (priv->flags != 0) {
1186
0
    g_variant_builder_add(builder,
1187
0
              "{sv}",
1188
0
              FWUPD_RESULT_KEY_FLAGS,
1189
0
              g_variant_new_uint64(priv->flags));
1190
0
  }
1191
0
  if (priv->level > 0) {
1192
0
    g_variant_builder_add(builder,
1193
0
              "{sv}",
1194
0
              FWUPD_RESULT_KEY_HSI_LEVEL,
1195
0
              g_variant_new_uint32(priv->level));
1196
0
  }
1197
0
  if (priv->result != FWUPD_SECURITY_ATTR_RESULT_UNKNOWN) {
1198
0
    g_variant_builder_add(builder,
1199
0
              "{sv}",
1200
0
              FWUPD_RESULT_KEY_HSI_RESULT,
1201
0
              g_variant_new_uint32(priv->result));
1202
0
  }
1203
0
  if (priv->result_fallback != FWUPD_SECURITY_ATTR_RESULT_UNKNOWN) {
1204
0
    g_variant_builder_add(builder,
1205
0
              "{sv}",
1206
0
              FWUPD_RESULT_KEY_HSI_RESULT_FALLBACK,
1207
0
              g_variant_new_uint32(priv->result_fallback));
1208
0
  }
1209
0
  if (priv->result_success != FWUPD_SECURITY_ATTR_RESULT_UNKNOWN) {
1210
0
    g_variant_builder_add(builder,
1211
0
              "{sv}",
1212
0
              FWUPD_RESULT_KEY_HSI_RESULT_SUCCESS,
1213
0
              g_variant_new_uint32(priv->result_success));
1214
0
  }
1215
0
  if (priv->metadata != NULL) {
1216
0
    g_variant_builder_add(builder,
1217
0
              "{sv}",
1218
0
              FWUPD_RESULT_KEY_METADATA,
1219
0
              fwupd_variant_from_hash_kv(priv->metadata));
1220
0
  }
1221
0
  if (priv->bios_setting_id != NULL) {
1222
0
    g_variant_builder_add(builder,
1223
0
              "{sv}",
1224
0
              FWUPD_RESULT_KEY_BIOS_SETTING_ID,
1225
0
              g_variant_new_string(priv->bios_setting_id));
1226
0
  }
1227
0
  if (priv->bios_setting_target_value != NULL) {
1228
0
    g_variant_builder_add(builder,
1229
0
              "{sv}",
1230
0
              FWUPD_RESULT_KEY_BIOS_SETTING_TARGET_VALUE,
1231
0
              g_variant_new_string(priv->bios_setting_target_value));
1232
0
  }
1233
0
  if (priv->bios_setting_current_value != NULL) {
1234
0
    g_variant_builder_add(builder,
1235
0
              "{sv}",
1236
0
              FWUPD_RESULT_KEY_BIOS_SETTING_CURRENT_VALUE,
1237
0
              g_variant_new_string(priv->bios_setting_current_value));
1238
0
  }
1239
0
  if (priv->kernel_current_value != NULL) {
1240
0
    g_variant_builder_add(builder,
1241
0
              "{sv}",
1242
0
              FWUPD_RESULT_KEY_KERNEL_CURRENT_VALUE,
1243
0
              g_variant_new_string(priv->kernel_current_value));
1244
0
  }
1245
0
  if (priv->kernel_target_value != NULL) {
1246
0
    g_variant_builder_add(builder,
1247
0
              "{sv}",
1248
0
              FWUPD_RESULT_KEY_KERNEL_TARGET_VALUE,
1249
0
              g_variant_new_string(priv->kernel_target_value));
1250
0
  }
1251
0
}
1252
1253
/**
1254
 * fwupd_security_attr_get_metadata:
1255
 * @self: a #FwupdSecurityAttr
1256
 * @key: metadata key
1257
 *
1258
 * Gets private metadata from the attribute which may be used in the name.
1259
 *
1260
 * Returns: (nullable): the metadata value, or %NULL if unfound
1261
 *
1262
 * Since: 1.5.0
1263
 **/
1264
const gchar *
1265
fwupd_security_attr_get_metadata(FwupdSecurityAttr *self, const gchar *key)
1266
0
{
1267
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
1268
1269
0
  g_return_val_if_fail(FWUPD_IS_SECURITY_ATTR(self), NULL);
1270
0
  g_return_val_if_fail(key != NULL, NULL);
1271
1272
0
  if (priv->metadata == NULL)
1273
0
    return NULL;
1274
0
  return g_hash_table_lookup(priv->metadata, key);
1275
0
}
1276
1277
/**
1278
 * fwupd_security_attr_add_metadata:
1279
 * @self: a #FwupdSecurityAttr
1280
 * @key: metadata key
1281
 * @value: (nullable): metadata value
1282
 *
1283
 * Adds metadata to the attribute which may be used in the name.
1284
 *
1285
 * Since: 1.5.0
1286
 **/
1287
void
1288
fwupd_security_attr_add_metadata(FwupdSecurityAttr *self, const gchar *key, const gchar *value)
1289
0
{
1290
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
1291
1292
0
  g_return_if_fail(FWUPD_IS_SECURITY_ATTR(self));
1293
0
  g_return_if_fail(key != NULL);
1294
1295
0
  if (priv->metadata == NULL) {
1296
0
    priv->metadata = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
1297
0
  }
1298
0
  g_hash_table_insert(priv->metadata, g_strdup(key), g_strdup(value));
1299
0
}
1300
1301
static void
1302
fwupd_security_attr_from_key_value(FwupdSecurityAttr *self, const gchar *key, GVariant *value)
1303
0
{
1304
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
1305
1306
0
  if (g_strcmp0(key, FWUPD_RESULT_KEY_APPSTREAM_ID) == 0) {
1307
0
    fwupd_security_attr_set_appstream_id(self, fwupd_variant_get_string(value));
1308
0
    return;
1309
0
  }
1310
0
  if (g_strcmp0(key, FWUPD_RESULT_KEY_CREATED) == 0) {
1311
0
    fwupd_security_attr_set_created(self, fwupd_variant_get_uint64(value));
1312
0
    return;
1313
0
  }
1314
0
  if (g_strcmp0(key, FWUPD_RESULT_KEY_NAME) == 0) {
1315
0
    fwupd_security_attr_set_name(self, fwupd_variant_get_string(value));
1316
0
    return;
1317
0
  }
1318
0
  if (g_strcmp0(key, FWUPD_RESULT_KEY_SUMMARY) == 0) {
1319
0
    fwupd_security_attr_set_title(self, fwupd_variant_get_string(value));
1320
0
    return;
1321
0
  }
1322
0
  if (g_strcmp0(key, FWUPD_RESULT_KEY_DESCRIPTION) == 0) {
1323
0
    fwupd_security_attr_set_description(self, fwupd_variant_get_string(value));
1324
0
    return;
1325
0
  }
1326
0
  if (g_strcmp0(key, FWUPD_RESULT_KEY_PLUGIN) == 0) {
1327
0
    fwupd_security_attr_set_plugin(self, fwupd_variant_get_string(value));
1328
0
    return;
1329
0
  }
1330
0
  if (g_strcmp0(key, FWUPD_RESULT_KEY_VERSION) == 0) {
1331
0
    fwupd_security_attr_set_fwupd_version(self, fwupd_variant_get_string(value));
1332
0
    return;
1333
0
  }
1334
0
  if (g_strcmp0(key, FWUPD_RESULT_KEY_URI) == 0) {
1335
0
    fwupd_security_attr_set_url(self, fwupd_variant_get_string(value));
1336
0
    return;
1337
0
  }
1338
0
  if (g_strcmp0(key, FWUPD_RESULT_KEY_FLAGS) == 0) {
1339
0
    fwupd_security_attr_set_flags(self, fwupd_variant_get_uint64(value));
1340
0
    return;
1341
0
  }
1342
0
  if (g_strcmp0(key, FWUPD_RESULT_KEY_HSI_LEVEL) == 0) {
1343
0
    fwupd_security_attr_set_level(self, fwupd_variant_get_uint32(value));
1344
0
    return;
1345
0
  }
1346
0
  if (g_strcmp0(key, FWUPD_RESULT_KEY_HSI_RESULT) == 0) {
1347
0
    fwupd_security_attr_set_result(self, fwupd_variant_get_uint32(value));
1348
0
    return;
1349
0
  }
1350
0
  if (g_strcmp0(key, FWUPD_RESULT_KEY_HSI_RESULT_FALLBACK) == 0) {
1351
0
    fwupd_security_attr_set_result_fallback(self, fwupd_variant_get_uint32(value));
1352
0
    return;
1353
0
  }
1354
0
  if (g_strcmp0(key, FWUPD_RESULT_KEY_HSI_RESULT_SUCCESS) == 0) {
1355
0
    fwupd_security_attr_set_result_success(self, fwupd_variant_get_uint32(value));
1356
0
    return;
1357
0
  }
1358
0
  if (g_strcmp0(key, FWUPD_RESULT_KEY_GUID) == 0) {
1359
0
    g_autofree const gchar **strv = fwupd_variant_get_strv(value);
1360
0
    for (guint i = 0; strv != NULL && strv[i] != NULL; i++)
1361
0
      fwupd_security_attr_add_guid(self, strv[i]);
1362
0
    return;
1363
0
  }
1364
0
  if (g_strcmp0(key, FWUPD_RESULT_KEY_METADATA) == 0) {
1365
0
    g_autoptr(GHashTable) hash = fwupd_variant_to_hash_kv(value);
1366
0
    if (hash != NULL) {
1367
0
      if (priv->metadata != NULL)
1368
0
        g_hash_table_unref(priv->metadata);
1369
0
      priv->metadata = g_steal_pointer(&hash);
1370
0
    }
1371
0
    return;
1372
0
  }
1373
0
  if (g_strcmp0(key, FWUPD_RESULT_KEY_BIOS_SETTING_ID) == 0) {
1374
0
    fwupd_security_attr_set_bios_setting_id(self, fwupd_variant_get_string(value));
1375
0
    return;
1376
0
  }
1377
0
  if (g_strcmp0(key, FWUPD_RESULT_KEY_BIOS_SETTING_TARGET_VALUE) == 0) {
1378
0
    fwupd_security_attr_set_bios_setting_target_value(self,
1379
0
                  fwupd_variant_get_string(value));
1380
0
    return;
1381
0
  }
1382
0
  if (g_strcmp0(key, FWUPD_RESULT_KEY_BIOS_SETTING_CURRENT_VALUE) == 0) {
1383
0
    fwupd_security_attr_set_bios_setting_current_value(self,
1384
0
                   fwupd_variant_get_string(value));
1385
0
    return;
1386
0
  }
1387
0
  if (g_strcmp0(key, FWUPD_RESULT_KEY_KERNEL_CURRENT_VALUE) == 0) {
1388
0
    fwupd_security_attr_set_kernel_current_value(self, fwupd_variant_get_string(value));
1389
0
    return;
1390
0
  }
1391
0
  if (g_strcmp0(key, FWUPD_RESULT_KEY_KERNEL_TARGET_VALUE) == 0) {
1392
0
    fwupd_security_attr_set_kernel_target_value(self, fwupd_variant_get_string(value));
1393
0
    return;
1394
0
  }
1395
0
}
1396
1397
static void
1398
fwupd_security_attr_string_append_tfl(GString *str,
1399
              guint idt,
1400
              const gchar *key,
1401
              FwupdSecurityAttrFlags security_attr_flags)
1402
0
{
1403
0
  g_autoptr(GString) tmp = g_string_new("");
1404
0
  for (guint i = 0; i < 64; i++) {
1405
0
    if ((security_attr_flags & ((guint64)1 << i)) == 0)
1406
0
      continue;
1407
0
    g_string_append_printf(tmp,
1408
0
               "%s|",
1409
0
               fwupd_security_attr_flag_to_string((guint64)1 << i));
1410
0
  }
1411
0
  if (tmp->len == 0) {
1412
0
    g_string_append(tmp, fwupd_security_attr_flag_to_string(0));
1413
0
  } else {
1414
0
    g_string_truncate(tmp, tmp->len - 1);
1415
0
  }
1416
0
  fwupd_codec_string_append(str, idt, key, tmp->str);
1417
0
}
1418
1419
static gboolean
1420
fwupd_security_attr_from_json(FwupdCodec *codec, FwupdJsonObject *json_obj, GError **error)
1421
0
{
1422
0
  FwupdSecurityAttr *self = FWUPD_SECURITY_ATTR(codec);
1423
0
  const gchar *tmp;
1424
0
  gint64 tmpi = 0;
1425
0
  g_autoptr(FwupdJsonArray) json_array1 = NULL;
1426
0
  g_autoptr(FwupdJsonArray) json_array2 = NULL;
1427
1428
  /* this has to exist */
1429
0
  tmp = fwupd_json_object_get_string(json_obj, FWUPD_RESULT_KEY_APPSTREAM_ID, error);
1430
0
  if (tmp == NULL)
1431
0
    return FALSE;
1432
0
  fwupd_security_attr_set_appstream_id(self, tmp);
1433
1434
  /* all optional */
1435
0
  fwupd_security_attr_set_name(
1436
0
      self,
1437
0
      fwupd_json_object_get_string(json_obj, FWUPD_RESULT_KEY_NAME, NULL));
1438
0
  fwupd_security_attr_set_title(
1439
0
      self,
1440
0
      fwupd_json_object_get_string(json_obj, FWUPD_RESULT_KEY_SUMMARY, NULL));
1441
0
  fwupd_security_attr_set_description(
1442
0
      self,
1443
0
      fwupd_json_object_get_string(json_obj, FWUPD_RESULT_KEY_DESCRIPTION, NULL));
1444
0
  fwupd_security_attr_set_plugin(
1445
0
      self,
1446
0
      fwupd_json_object_get_string(json_obj, FWUPD_RESULT_KEY_PLUGIN, NULL));
1447
0
  fwupd_security_attr_set_fwupd_version(
1448
0
      self,
1449
0
      fwupd_json_object_get_string(json_obj, FWUPD_RESULT_KEY_VERSION, NULL));
1450
0
  fwupd_security_attr_set_url(
1451
0
      self,
1452
0
      fwupd_json_object_get_string(json_obj, FWUPD_RESULT_KEY_URI, NULL));
1453
0
  if (!fwupd_json_object_get_integer_with_default(json_obj,
1454
0
              FWUPD_RESULT_KEY_HSI_LEVEL,
1455
0
              &tmpi,
1456
0
              0,
1457
0
              error))
1458
0
    return FALSE;
1459
0
  fwupd_security_attr_set_level(self, tmpi);
1460
0
  if (!fwupd_json_object_get_integer_with_default(json_obj,
1461
0
              FWUPD_RESULT_KEY_CREATED,
1462
0
              &tmpi,
1463
0
              0,
1464
0
              error))
1465
0
    return FALSE;
1466
0
  fwupd_security_attr_set_created(self, tmpi);
1467
0
  fwupd_security_attr_set_bios_setting_id(
1468
0
      self,
1469
0
      fwupd_json_object_get_string(json_obj, FWUPD_RESULT_KEY_BIOS_SETTING_ID, NULL));
1470
0
  fwupd_security_attr_set_bios_setting_target_value(
1471
0
      self,
1472
0
      fwupd_json_object_get_string(json_obj,
1473
0
           FWUPD_RESULT_KEY_BIOS_SETTING_TARGET_VALUE,
1474
0
           NULL));
1475
0
  fwupd_security_attr_set_bios_setting_current_value(
1476
0
      self,
1477
0
      fwupd_json_object_get_string(json_obj,
1478
0
           FWUPD_RESULT_KEY_BIOS_SETTING_CURRENT_VALUE,
1479
0
           NULL));
1480
0
  fwupd_security_attr_set_kernel_current_value(
1481
0
      self,
1482
0
      fwupd_json_object_get_string(json_obj, FWUPD_RESULT_KEY_KERNEL_CURRENT_VALUE, NULL));
1483
0
  fwupd_security_attr_set_kernel_target_value(
1484
0
      self,
1485
0
      fwupd_json_object_get_string(json_obj, FWUPD_RESULT_KEY_KERNEL_TARGET_VALUE, NULL));
1486
1487
  /* also optional */
1488
0
  tmp = fwupd_json_object_get_string(json_obj, FWUPD_RESULT_KEY_HSI_RESULT, NULL);
1489
0
  if (tmp != NULL)
1490
0
    fwupd_security_attr_set_result(self, fwupd_security_attr_result_from_string(tmp));
1491
1492
0
  tmp = fwupd_json_object_get_string(json_obj, FWUPD_RESULT_KEY_HSI_RESULT_FALLBACK, NULL);
1493
0
  if (tmp != NULL) {
1494
0
    fwupd_security_attr_set_result_fallback(
1495
0
        self,
1496
0
        fwupd_security_attr_result_from_string(tmp));
1497
0
  }
1498
0
  tmp = fwupd_json_object_get_string(json_obj, FWUPD_RESULT_KEY_HSI_RESULT_SUCCESS, NULL);
1499
0
  if (tmp != NULL) {
1500
0
    fwupd_security_attr_set_result_success(self,
1501
0
                   fwupd_security_attr_result_from_string(tmp));
1502
0
  }
1503
0
  json_array1 = fwupd_json_object_get_array(json_obj, FWUPD_RESULT_KEY_FLAGS, NULL);
1504
0
  if (json_array1 != NULL) {
1505
0
    for (guint i = 0; i < fwupd_json_array_get_size(json_array1); i++) {
1506
0
      FwupdSecurityAttrFlags flag = fwupd_security_attr_flag_from_string(
1507
0
          fwupd_json_array_get_string(json_array1, i, NULL));
1508
0
      if (flag != FWUPD_SECURITY_ATTR_FLAG_NONE)
1509
0
        fwupd_security_attr_add_flag(self, flag);
1510
0
    }
1511
0
  }
1512
0
  json_array2 = fwupd_json_object_get_array(json_obj, FWUPD_RESULT_KEY_GUID, NULL);
1513
0
  if (json_array2 != NULL) {
1514
0
    for (guint i = 0; i < fwupd_json_array_get_size(json_array2); i++) {
1515
0
      fwupd_security_attr_add_guid(
1516
0
          self,
1517
0
          fwupd_json_array_get_string(json_array2, i, NULL));
1518
0
    }
1519
0
  }
1520
1521
  /* success */
1522
0
  return TRUE;
1523
0
}
1524
1525
static void
1526
fwupd_security_attr_add_json(FwupdCodec *codec, FwupdJsonObject *json_obj, FwupdCodecFlags flags)
1527
0
{
1528
0
  FwupdSecurityAttr *self = FWUPD_SECURITY_ATTR(codec);
1529
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
1530
1531
0
  if (priv->appstream_id != NULL)
1532
0
    fwupd_json_object_add_string(json_obj,
1533
0
               FWUPD_RESULT_KEY_APPSTREAM_ID,
1534
0
               priv->appstream_id);
1535
0
  if (priv->created > 0)
1536
0
    fwupd_json_object_add_integer(json_obj, FWUPD_RESULT_KEY_CREATED, priv->created);
1537
0
  if (priv->level > 0)
1538
0
    fwupd_json_object_add_integer(json_obj, FWUPD_RESULT_KEY_HSI_LEVEL, priv->level);
1539
0
  if (priv->result != FWUPD_SECURITY_ATTR_RESULT_UNKNOWN)
1540
0
    fwupd_json_object_add_string(json_obj,
1541
0
               FWUPD_RESULT_KEY_HSI_RESULT,
1542
0
               fwupd_security_attr_result_to_string(priv->result));
1543
0
  if (priv->result_fallback != FWUPD_SECURITY_ATTR_RESULT_UNKNOWN) {
1544
0
    fwupd_json_object_add_string(
1545
0
        json_obj,
1546
0
        FWUPD_RESULT_KEY_HSI_RESULT_FALLBACK,
1547
0
        fwupd_security_attr_result_to_string(priv->result_fallback));
1548
0
  }
1549
0
  if (priv->result_success != FWUPD_SECURITY_ATTR_RESULT_UNKNOWN) {
1550
0
    fwupd_json_object_add_string(
1551
0
        json_obj,
1552
0
        FWUPD_RESULT_KEY_HSI_RESULT_SUCCESS,
1553
0
        fwupd_security_attr_result_to_string(priv->result_success));
1554
0
  }
1555
0
  if (priv->name != NULL)
1556
0
    fwupd_json_object_add_string(json_obj, FWUPD_RESULT_KEY_NAME, priv->name);
1557
0
  if (priv->title != NULL)
1558
0
    fwupd_json_object_add_string(json_obj, FWUPD_RESULT_KEY_SUMMARY, priv->title);
1559
0
  if (priv->description != NULL) {
1560
0
    fwupd_json_object_add_string(json_obj,
1561
0
               FWUPD_RESULT_KEY_DESCRIPTION,
1562
0
               priv->description);
1563
0
  }
1564
0
  if (priv->plugin != NULL)
1565
0
    fwupd_json_object_add_string(json_obj, FWUPD_RESULT_KEY_PLUGIN, priv->plugin);
1566
0
  if (priv->fwupd_version != NULL) {
1567
0
    fwupd_json_object_add_string(json_obj,
1568
0
               FWUPD_RESULT_KEY_VERSION,
1569
0
               priv->fwupd_version);
1570
0
  }
1571
0
  if (priv->url != NULL)
1572
0
    fwupd_json_object_add_string(json_obj, FWUPD_RESULT_KEY_URI, priv->url);
1573
0
  if (priv->bios_setting_target_value != NULL) {
1574
0
    fwupd_json_object_add_string(json_obj,
1575
0
               FWUPD_RESULT_KEY_BIOS_SETTING_TARGET_VALUE,
1576
0
               priv->bios_setting_target_value);
1577
0
  }
1578
0
  if (priv->bios_setting_current_value != NULL) {
1579
0
    fwupd_json_object_add_string(json_obj,
1580
0
               FWUPD_RESULT_KEY_BIOS_SETTING_CURRENT_VALUE,
1581
0
               priv->bios_setting_current_value);
1582
0
  }
1583
0
  if (priv->bios_setting_id != NULL) {
1584
0
    fwupd_json_object_add_string(json_obj,
1585
0
               FWUPD_RESULT_KEY_BIOS_SETTING_ID,
1586
0
               priv->bios_setting_id);
1587
0
  }
1588
0
  if (priv->kernel_current_value != NULL) {
1589
0
    fwupd_json_object_add_string(json_obj,
1590
0
               FWUPD_RESULT_KEY_KERNEL_CURRENT_VALUE,
1591
0
               priv->kernel_current_value);
1592
0
  }
1593
0
  if (priv->kernel_target_value != NULL) {
1594
0
    fwupd_json_object_add_string(json_obj,
1595
0
               FWUPD_RESULT_KEY_KERNEL_TARGET_VALUE,
1596
0
               priv->kernel_target_value);
1597
0
  }
1598
1599
0
  if (priv->flags != FWUPD_SECURITY_ATTR_FLAG_NONE) {
1600
0
    g_autoptr(FwupdJsonArray) json_arr = fwupd_json_array_new();
1601
0
    for (guint i = 0; i < 64; i++) {
1602
0
      const gchar *tmp;
1603
0
      if ((priv->flags & ((guint64)1 << i)) == 0)
1604
0
        continue;
1605
0
      tmp = fwupd_security_attr_flag_to_string((guint64)1 << i);
1606
0
      if (tmp != NULL)
1607
0
        fwupd_json_array_add_string(json_arr, tmp);
1608
0
    }
1609
0
    fwupd_json_object_add_array(json_obj, FWUPD_RESULT_KEY_FLAGS, json_arr);
1610
0
  }
1611
0
  if (priv->guids->len > 0) {
1612
0
    g_autoptr(FwupdJsonArray) json_arr = fwupd_json_array_new();
1613
0
    for (guint i = 0; i < priv->guids->len; i++) {
1614
0
      const gchar *guid = g_ptr_array_index(priv->guids, i);
1615
0
      fwupd_json_array_add_string(json_arr, guid);
1616
0
    }
1617
0
    fwupd_json_object_add_array(json_obj, FWUPD_RESULT_KEY_GUID, json_arr);
1618
0
  }
1619
0
  if (priv->metadata != NULL) {
1620
0
    g_autoptr(GList) keys =
1621
0
        g_list_sort(g_hash_table_get_keys(priv->metadata), (GCompareFunc)g_strcmp0);
1622
0
    for (GList *l = keys; l != NULL; l = l->next) {
1623
0
      const gchar *key = l->data;
1624
0
      const gchar *value = g_hash_table_lookup(priv->metadata, key);
1625
0
      fwupd_json_object_add_string(json_obj, key, value);
1626
0
    }
1627
0
  }
1628
0
}
1629
1630
static void
1631
fwupd_security_attr_add_string(FwupdCodec *codec, guint idt, GString *str)
1632
0
{
1633
0
  FwupdSecurityAttr *self = FWUPD_SECURITY_ATTR(codec);
1634
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
1635
0
  fwupd_codec_string_append(str, idt, FWUPD_RESULT_KEY_APPSTREAM_ID, priv->appstream_id);
1636
0
  fwupd_codec_string_append_time(str, idt, FWUPD_RESULT_KEY_CREATED, priv->created);
1637
0
  fwupd_codec_string_append_int(str, idt, FWUPD_RESULT_KEY_HSI_LEVEL, priv->level);
1638
0
  fwupd_codec_string_append(str,
1639
0
          idt,
1640
0
          FWUPD_RESULT_KEY_HSI_RESULT,
1641
0
          fwupd_security_attr_result_to_string(priv->result));
1642
0
  fwupd_codec_string_append(str,
1643
0
          idt,
1644
0
          FWUPD_RESULT_KEY_HSI_RESULT_FALLBACK,
1645
0
          fwupd_security_attr_result_to_string(priv->result_fallback));
1646
0
  fwupd_codec_string_append(str,
1647
0
          idt,
1648
0
          FWUPD_RESULT_KEY_HSI_RESULT_SUCCESS,
1649
0
          fwupd_security_attr_result_to_string(priv->result_success));
1650
0
  if (priv->flags != FWUPD_SECURITY_ATTR_FLAG_NONE)
1651
0
    fwupd_security_attr_string_append_tfl(str,
1652
0
                  idt,
1653
0
                  FWUPD_RESULT_KEY_FLAGS,
1654
0
                  priv->flags);
1655
0
  fwupd_codec_string_append(str, idt, FWUPD_RESULT_KEY_NAME, priv->name);
1656
0
  fwupd_codec_string_append(str, idt, FWUPD_RESULT_KEY_SUMMARY, priv->title);
1657
0
  fwupd_codec_string_append(str, idt, FWUPD_RESULT_KEY_DESCRIPTION, priv->description);
1658
0
  fwupd_codec_string_append(str, idt, FWUPD_RESULT_KEY_PLUGIN, priv->plugin);
1659
0
  fwupd_codec_string_append(str, idt, FWUPD_RESULT_KEY_VERSION, priv->fwupd_version);
1660
0
  fwupd_codec_string_append(str, idt, FWUPD_RESULT_KEY_URI, priv->url);
1661
0
  fwupd_codec_string_append(str,
1662
0
          idt,
1663
0
          FWUPD_RESULT_KEY_BIOS_SETTING_ID,
1664
0
          priv->bios_setting_id);
1665
0
  fwupd_codec_string_append(str,
1666
0
          idt,
1667
0
          FWUPD_RESULT_KEY_BIOS_SETTING_TARGET_VALUE,
1668
0
          priv->bios_setting_target_value);
1669
0
  fwupd_codec_string_append(str,
1670
0
          idt,
1671
0
          FWUPD_RESULT_KEY_BIOS_SETTING_CURRENT_VALUE,
1672
0
          priv->bios_setting_current_value);
1673
0
  fwupd_codec_string_append(str,
1674
0
          idt,
1675
0
          FWUPD_RESULT_KEY_KERNEL_CURRENT_VALUE,
1676
0
          priv->kernel_current_value);
1677
0
  fwupd_codec_string_append(str,
1678
0
          idt,
1679
0
          FWUPD_RESULT_KEY_KERNEL_TARGET_VALUE,
1680
0
          priv->kernel_target_value);
1681
1682
0
  for (guint i = 0; i < priv->obsoletes->len; i++) {
1683
0
    const gchar *appstream_id = g_ptr_array_index(priv->obsoletes, i);
1684
0
    fwupd_codec_string_append(str, idt, "Obsolete", appstream_id);
1685
0
  }
1686
0
  for (guint i = 0; i < priv->guids->len; i++) {
1687
0
    const gchar *guid = g_ptr_array_index(priv->guids, i);
1688
0
    fwupd_codec_string_append(str, idt, FWUPD_RESULT_KEY_GUID, guid);
1689
0
  }
1690
0
  if (priv->metadata != NULL) {
1691
0
    g_autoptr(GList) keys =
1692
0
        g_list_sort(g_hash_table_get_keys(priv->metadata), (GCompareFunc)g_strcmp0);
1693
0
    for (GList *l = keys; l != NULL; l = l->next) {
1694
0
      const gchar *key = l->data;
1695
0
      const gchar *value = g_hash_table_lookup(priv->metadata, key);
1696
0
      fwupd_codec_string_append(str, idt, key, value);
1697
0
    }
1698
0
  }
1699
0
}
1700
1701
static void
1702
fwupd_security_attr_class_init(FwupdSecurityAttrClass *klass)
1703
0
{
1704
0
  GObjectClass *object_class = G_OBJECT_CLASS(klass);
1705
0
  object_class->finalize = fwupd_security_attr_finalize;
1706
0
}
1707
1708
static void
1709
fwupd_security_attr_init(FwupdSecurityAttr *self)
1710
0
{
1711
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
1712
0
  priv->level = FWUPD_SECURITY_ATTR_LEVEL_NONE;
1713
0
  priv->obsoletes = g_ptr_array_new_with_free_func(g_free);
1714
0
  priv->guids = g_ptr_array_new_with_free_func(g_free);
1715
0
  priv->created = (guint64)g_get_real_time() / G_USEC_PER_SEC;
1716
0
}
1717
1718
static void
1719
fwupd_security_attr_finalize(GObject *object)
1720
0
{
1721
0
  FwupdSecurityAttr *self = FWUPD_SECURITY_ATTR(object);
1722
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
1723
1724
0
  if (priv->metadata != NULL)
1725
0
    g_hash_table_unref(priv->metadata);
1726
0
  g_free(priv->bios_setting_id);
1727
0
  g_free(priv->bios_setting_target_value);
1728
0
  g_free(priv->bios_setting_current_value);
1729
0
  g_free(priv->kernel_current_value);
1730
0
  g_free(priv->kernel_target_value);
1731
0
  g_free(priv->appstream_id);
1732
0
  g_free(priv->name);
1733
0
  g_free(priv->title);
1734
0
  g_free(priv->description);
1735
0
  g_free(priv->plugin);
1736
0
  g_free(priv->fwupd_version);
1737
0
  g_free(priv->url);
1738
0
  g_ptr_array_unref(priv->obsoletes);
1739
0
  g_ptr_array_unref(priv->guids);
1740
1741
0
  G_OBJECT_CLASS(fwupd_security_attr_parent_class)->finalize(object);
1742
0
}
1743
1744
static void
1745
fwupd_security_attr_from_variant_iter(FwupdCodec *codec, GVariantIter *iter)
1746
0
{
1747
0
  FwupdSecurityAttr *self = FWUPD_SECURITY_ATTR(codec);
1748
0
  GVariant *value;
1749
0
  const gchar *key;
1750
0
  while (g_variant_iter_next(iter, "{&sv}", &key, &value)) {
1751
0
    fwupd_security_attr_from_key_value(self, key, value);
1752
0
    g_variant_unref(value);
1753
0
  }
1754
0
}
1755
1756
static void
1757
fwupd_security_attr_codec_iface_init(FwupdCodecInterface *iface)
1758
0
{
1759
0
  iface->add_string = fwupd_security_attr_add_string;
1760
0
  iface->add_json = fwupd_security_attr_add_json;
1761
0
  iface->from_json = fwupd_security_attr_from_json;
1762
0
  iface->add_variant = fwupd_security_attr_add_variant;
1763
0
  iface->from_variant_iter = fwupd_security_attr_from_variant_iter;
1764
0
}
1765
1766
/**
1767
 * fwupd_security_attr_copy:
1768
 * @self: (nullable): a #FwupdSecurityAttr
1769
 *
1770
 * Makes a full (deep) copy of a security attribute.
1771
 *
1772
 * Returns: (transfer full): a new #FwupdSecurityAttr
1773
 *
1774
 * Since: 1.7.1
1775
 **/
1776
FwupdSecurityAttr *
1777
fwupd_security_attr_copy(FwupdSecurityAttr *self)
1778
0
{
1779
0
  g_autoptr(FwupdSecurityAttr) new = g_object_new(FWUPD_TYPE_SECURITY_ATTR, NULL);
1780
0
  FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self);
1781
1782
0
  g_return_val_if_fail(FWUPD_IS_SECURITY_ATTR(self), NULL);
1783
1784
0
  fwupd_security_attr_set_appstream_id(new, priv->appstream_id);
1785
0
  fwupd_security_attr_set_name(new, priv->name);
1786
0
  fwupd_security_attr_set_title(new, priv->title);
1787
0
  fwupd_security_attr_set_description(new, priv->description);
1788
0
  fwupd_security_attr_set_plugin(new, priv->plugin);
1789
0
  fwupd_security_attr_set_fwupd_version(new, priv->fwupd_version);
1790
0
  fwupd_security_attr_set_url(new, priv->url);
1791
0
  fwupd_security_attr_set_level(new, priv->level);
1792
0
  fwupd_security_attr_set_flags(new, priv->flags);
1793
0
  fwupd_security_attr_set_result(new, priv->result);
1794
0
  fwupd_security_attr_set_result_fallback(new, priv->result_fallback);
1795
0
  fwupd_security_attr_set_result_success(new, priv->result_success);
1796
0
  fwupd_security_attr_set_created(new, priv->created);
1797
0
  fwupd_security_attr_set_bios_setting_id(new, priv->bios_setting_id);
1798
0
  fwupd_security_attr_set_bios_setting_target_value(new, priv->bios_setting_target_value);
1799
0
  fwupd_security_attr_set_bios_setting_current_value(new, priv->bios_setting_current_value);
1800
0
  fwupd_security_attr_set_kernel_current_value(new, priv->kernel_current_value);
1801
0
  fwupd_security_attr_set_kernel_target_value(new, priv->kernel_target_value);
1802
1803
0
  for (guint i = 0; i < priv->guids->len; i++) {
1804
0
    const gchar *guid = g_ptr_array_index(priv->guids, i);
1805
0
    fwupd_security_attr_add_guid(new, guid);
1806
0
  }
1807
0
  for (guint i = 0; i < priv->obsoletes->len; i++) {
1808
0
    const gchar *obsolete = g_ptr_array_index(priv->obsoletes, i);
1809
0
    fwupd_security_attr_add_obsolete(new, obsolete);
1810
0
  }
1811
0
  if (priv->metadata != NULL) {
1812
0
    GHashTableIter iter;
1813
0
    gpointer key;
1814
0
    gpointer value;
1815
0
    g_hash_table_iter_init(&iter, priv->metadata);
1816
0
    while (g_hash_table_iter_next(&iter, &key, &value)) {
1817
0
      fwupd_security_attr_add_metadata(new,
1818
0
               (const gchar *)key,
1819
0
               (const gchar *)value);
1820
0
    }
1821
0
  }
1822
0
  return g_steal_pointer(&new);
1823
0
}
1824
1825
/**
1826
 * fwupd_security_attr_new:
1827
 * @appstream_id: (nullable): the AppStream component ID, e.g. `com.intel.BiosGuard`
1828
 *
1829
 * Creates a new security attribute.
1830
 *
1831
 * Plugins should not use this method, and should instead use `fu_plugin_security_attr_new()` or
1832
 * `fu_security_attr_new()`.
1833
 *
1834
 * Returns: a new #FwupdSecurityAttr
1835
 *
1836
 * Since: 1.5.0
1837
 **/
1838
FwupdSecurityAttr *
1839
fwupd_security_attr_new(const gchar *appstream_id)
1840
0
{
1841
0
  FwupdSecurityAttr *self;
1842
0
  self = g_object_new(FWUPD_TYPE_SECURITY_ATTR, NULL);
1843
0
  if (appstream_id != NULL)
1844
0
    fwupd_security_attr_set_appstream_id(self, appstream_id);
1845
0
  return FWUPD_SECURITY_ATTR(self);
1846
0
}