/src/fwupd/libfwupdplugin/fu-security-attr.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright 2022 Richard Hughes <richard@hughsie.com> |
3 | | * |
4 | | * SPDX-License-Identifier: LGPL-2.1-or-later |
5 | | */ |
6 | | |
7 | 0 | #define G_LOG_DOMAIN "FuSecurityAttr" |
8 | | |
9 | | #include "config.h" |
10 | | |
11 | | #include "fwupd-security-attr-private.h" |
12 | | |
13 | | #include "fu-security-attr.h" |
14 | | #include "fu-version-common.h" |
15 | | |
16 | | typedef struct { |
17 | | FuContext *ctx; |
18 | | } FuSecurityAttrPrivate; |
19 | | |
20 | 0 | G_DEFINE_TYPE_WITH_PRIVATE(FuSecurityAttr, fu_security_attr, FWUPD_TYPE_SECURITY_ATTR) |
21 | 0 |
|
22 | 0 | #define GET_PRIVATE(o) (fu_security_attr_get_instance_private(o)) |
23 | | |
24 | | /** |
25 | | * fu_security_attr_check_fwupd_version: |
26 | | * @self: a #FuSecurityAttr |
27 | | * @fwupd_version: a fwupd version, e.g. `2.0.7` |
28 | | * |
29 | | * Checks if this attribute was available in a given fwupd release. |
30 | | * |
31 | | * If @fwupd_version is %NULL then expect %TRUE. |
32 | | * |
33 | | * Returns: %TRUE if the fwupd release contained this attribute |
34 | | * |
35 | | * Since: 2.0.7 |
36 | | **/ |
37 | | gboolean |
38 | | fu_security_attr_check_fwupd_version(FuSecurityAttr *self, const gchar *fwupd_version) |
39 | 0 | { |
40 | 0 | g_return_val_if_fail(FU_IS_SECURITY_ATTR(self), FALSE); |
41 | 0 | if (fwupd_version == NULL) |
42 | 0 | return TRUE; |
43 | 0 | if (fu_security_attr_get_fwupd_version(self) == NULL) |
44 | 0 | return TRUE; |
45 | 0 | return fu_version_compare(fwupd_version, |
46 | 0 | fu_security_attr_get_fwupd_version(self), |
47 | 0 | FWUPD_VERSION_FORMAT_UNKNOWN) >= 0; |
48 | 0 | } |
49 | | |
50 | | /** |
51 | | * fu_security_attr_add_bios_target_value: |
52 | | * @self: a #FuSecurityAttr |
53 | | * @id: a #FwupdBiosSetting ID or name |
54 | | * @needle: The substring of a target value |
55 | | * |
56 | | * Checks all configured possible values of an enumeration attribute and |
57 | | * if any match @needle then set as the target value. |
58 | | * |
59 | | * Since: 1.8.4 |
60 | | **/ |
61 | | void |
62 | | fu_security_attr_add_bios_target_value(FuSecurityAttr *self, const gchar *id, const gchar *needle) |
63 | 0 | { |
64 | 0 | FuSecurityAttrPrivate *priv = GET_PRIVATE(self); |
65 | 0 | FwupdBiosSetting *bios_setting; |
66 | 0 | GPtrArray *values; |
67 | 0 | const gchar *current; |
68 | |
|
69 | 0 | bios_setting = fu_context_get_bios_setting(priv->ctx, id); |
70 | 0 | if (bios_setting == NULL) |
71 | 0 | return; |
72 | 0 | current = fwupd_bios_setting_get_current_value(bios_setting); |
73 | 0 | fu_security_attr_set_bios_setting_id(self, fwupd_bios_setting_get_id(bios_setting)); |
74 | 0 | fu_security_attr_set_bios_setting_current_value(self, current); |
75 | 0 | if (fwupd_bios_setting_get_kind(bios_setting) != FWUPD_BIOS_SETTING_KIND_ENUMERATION) |
76 | 0 | return; |
77 | 0 | if (fwupd_bios_setting_get_read_only(bios_setting)) |
78 | 0 | return; |
79 | 0 | values = fwupd_bios_setting_get_possible_values(bios_setting); |
80 | 0 | for (guint i = 0; i < values->len; i++) { |
81 | 0 | const gchar *possible = g_ptr_array_index(values, i); |
82 | 0 | g_autofree gchar *lower = g_utf8_strdown(possible, -1); |
83 | 0 | if (g_strrstr(lower, needle)) { |
84 | 0 | fu_security_attr_set_bios_setting_target_value(self, possible); |
85 | | /* this is built-in to the engine */ |
86 | 0 | if (g_strcmp0(possible, current) != 0) { |
87 | 0 | fu_security_attr_add_flag(self, FWUPD_SECURITY_ATTR_FLAG_CAN_FIX); |
88 | 0 | fu_security_attr_add_flag(self, FWUPD_SECURITY_ATTR_FLAG_CAN_UNDO); |
89 | 0 | } |
90 | 0 | return; |
91 | 0 | } |
92 | 0 | } |
93 | 0 | } |
94 | | |
95 | | static FuContext * |
96 | | fu_security_attr_get_context(FuSecurityAttr *self) |
97 | 0 | { |
98 | 0 | FuSecurityAttrPrivate *priv = GET_PRIVATE(self); |
99 | 0 | g_return_val_if_fail(FU_IS_SECURITY_ATTR(self), NULL); |
100 | 0 | return priv->ctx; |
101 | 0 | } |
102 | | |
103 | | static void |
104 | | fu_security_attr_set_context(FuSecurityAttr *self, FuContext *ctx) |
105 | 0 | { |
106 | 0 | FuSecurityAttrPrivate *priv = GET_PRIVATE(self); |
107 | 0 | g_return_if_fail(FU_IS_SECURITY_ATTR(self)); |
108 | 0 | g_return_if_fail(FU_IS_CONTEXT(ctx)); |
109 | 0 | g_set_object(&priv->ctx, ctx); |
110 | 0 | } |
111 | | |
112 | | /** |
113 | | * fu_security_attr_copy: |
114 | | * @donor: a #FuSecurityAttr |
115 | | * |
116 | | * Makes a full (deep) copy of a security attribute. |
117 | | * |
118 | | * Returns: (transfer full): a #FuSecurityAttr |
119 | | * |
120 | | * Since: 2.1.8 |
121 | | **/ |
122 | | FuSecurityAttr * |
123 | | fu_security_attr_copy(FuSecurityAttr *donor) |
124 | 0 | { |
125 | 0 | g_autoptr(FuSecurityAttr) self = g_object_new(FU_TYPE_SECURITY_ATTR, NULL); |
126 | 0 | fu_security_attr_set_context(self, fu_security_attr_get_context(donor)); |
127 | 0 | fwupd_security_attr_incorporate(FWUPD_SECURITY_ATTR(self), FWUPD_SECURITY_ATTR(donor)); |
128 | 0 | fwupd_security_attr_set_created( |
129 | 0 | FWUPD_SECURITY_ATTR(self), |
130 | 0 | fwupd_security_attr_get_created(FWUPD_SECURITY_ATTR(donor))); |
131 | 0 | return g_steal_pointer(&self); |
132 | 0 | } |
133 | | |
134 | | static void |
135 | | fu_security_attr_init(FuSecurityAttr *self) |
136 | 0 | { |
137 | 0 | } |
138 | | |
139 | | static void |
140 | | fu_security_attr_dispose(GObject *object) |
141 | 0 | { |
142 | 0 | FuSecurityAttr *self = FU_SECURITY_ATTR(object); |
143 | 0 | FuSecurityAttrPrivate *priv = GET_PRIVATE(self); |
144 | 0 | g_clear_object(&priv->ctx); |
145 | 0 | G_OBJECT_CLASS(fu_security_attr_parent_class)->dispose(object); |
146 | 0 | } |
147 | | |
148 | | static void |
149 | | fu_security_attr_class_init(FuSecurityAttrClass *klass) |
150 | 0 | { |
151 | 0 | GObjectClass *object_class = G_OBJECT_CLASS(klass); |
152 | 0 | object_class->dispose = fu_security_attr_dispose; |
153 | 0 | } |
154 | | |
155 | | /** |
156 | | * fu_security_attr_new: |
157 | | * @ctx: a #FuContext |
158 | | * @appstream_id: (nullable): the AppStream component ID, e.g. `com.intel.BiosGuard` |
159 | | * |
160 | | * Creates a new #FuSecurityAttr with context set. |
161 | | * |
162 | | * Returns: (transfer full): a #FuSecurityAttr |
163 | | * |
164 | | * Since: 1.8.4 |
165 | | **/ |
166 | | FuSecurityAttr * |
167 | | fu_security_attr_new(FuContext *ctx, const gchar *appstream_id) |
168 | 0 | { |
169 | 0 | g_autoptr(FuSecurityAttr) self = g_object_new(FU_TYPE_SECURITY_ATTR, NULL); |
170 | 0 | g_return_val_if_fail(FU_IS_CONTEXT(ctx), NULL); |
171 | 0 | if (appstream_id != NULL) |
172 | 0 | fu_security_attr_set_appstream_id(FWUPD_SECURITY_ATTR(self), appstream_id); |
173 | 0 | fu_security_attr_set_context(self, ctx); |
174 | 0 | return g_steal_pointer(&self); |
175 | 0 | } |