Coverage Report

Created: 2025-08-26 06:55

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