mirror of
https://git.proxmox.com/git/fwupd
synced 2025-06-05 12:00:24 +00:00
redfish: Change an expired password when required
This commit is contained in:
parent
0264c29bda
commit
3917714dd1
@ -59,6 +59,8 @@ fwupd_error_to_string(FwupdError error)
|
||||
return FWUPD_DBUS_INTERFACE ".BatteryLevelTooLow";
|
||||
if (error == FWUPD_ERROR_NEEDS_USER_ACTION)
|
||||
return FWUPD_DBUS_INTERFACE ".NeedsUserAction";
|
||||
if (error == FWUPD_ERROR_AUTH_EXPIRED)
|
||||
return FWUPD_DBUS_INTERFACE ".AuthExpired";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -109,6 +111,8 @@ fwupd_error_from_string(const gchar *error)
|
||||
return FWUPD_ERROR_BATTERY_LEVEL_TOO_LOW;
|
||||
if (g_strcmp0(error, FWUPD_DBUS_INTERFACE ".NeedsUserAction") == 0)
|
||||
return FWUPD_ERROR_NEEDS_USER_ACTION;
|
||||
if (g_strcmp0(error, FWUPD_DBUS_INTERFACE ".AuthExpired") == 0)
|
||||
return FWUPD_ERROR_AUTH_EXPIRED;
|
||||
return FWUPD_ERROR_LAST;
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,7 @@ G_BEGIN_DECLS
|
||||
* @FWUPD_ERROR_BROKEN_SYSTEM: User has configured their system in a broken way
|
||||
* @FWUPD_ERROR_BATTERY_LEVEL_TOO_LOW: The system battery level is too low
|
||||
* @FWUPD_ERROR_NEEDS_USER_ACTION: User needs to do an action to complete the update
|
||||
* @FWUPD_ERROR_AUTH_EXPIRED: Failed to get auth as credentials have expired
|
||||
*
|
||||
* The error code.
|
||||
**/
|
||||
@ -52,6 +53,7 @@ typedef enum {
|
||||
FWUPD_ERROR_BROKEN_SYSTEM, /* Since: 1.2.8 */
|
||||
FWUPD_ERROR_BATTERY_LEVEL_TOO_LOW, /* Since: 1.2.10 */
|
||||
FWUPD_ERROR_NEEDS_USER_ACTION, /* Since: 1.3.3 */
|
||||
FWUPD_ERROR_AUTH_EXPIRED, /* Since: 1.7.5 */
|
||||
/*< private >*/
|
||||
FWUPD_ERROR_LAST
|
||||
} FwupdError;
|
||||
|
@ -21,6 +21,55 @@ struct FuPluginData {
|
||||
FuRedfishBackend *backend;
|
||||
};
|
||||
|
||||
static gchar *
|
||||
fu_common_generate_password(guint length)
|
||||
{
|
||||
GString *str = g_string_sized_new(length);
|
||||
|
||||
/* get a random password string */
|
||||
while (str->len < length) {
|
||||
gchar tmp = (gchar)g_random_int_range(0x0, 0xff);
|
||||
if (g_ascii_isalnum(tmp))
|
||||
g_string_append_c(str, tmp);
|
||||
}
|
||||
return g_string_free(str, FALSE);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_plugin_redfish_change_expired(FuPlugin *plugin, GError **error)
|
||||
{
|
||||
FuPluginData *data = fu_plugin_get_data(plugin);
|
||||
g_autofree gchar *password_new = fu_common_generate_password(15);
|
||||
g_autofree gchar *uri = NULL;
|
||||
g_autoptr(FuRedfishRequest) request = NULL;
|
||||
g_autoptr(JsonBuilder) builder = json_builder_new();
|
||||
|
||||
/* select correct, falling back to default for old fwupd versions */
|
||||
uri = fu_plugin_get_config_value(plugin, "UserUri");
|
||||
if (uri == NULL) {
|
||||
uri = g_strdup("/redfish/v1/AccountService/Accounts/2");
|
||||
if (!fu_plugin_set_secure_config_value(plugin, "UserUri", uri, error))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* now use Redfish to change the temporary password to the actual password */
|
||||
request = fu_redfish_backend_request_new(data->backend);
|
||||
json_builder_begin_object(builder);
|
||||
json_builder_set_member_name(builder, "Password");
|
||||
json_builder_add_string_value(builder, password_new);
|
||||
json_builder_end_object(builder);
|
||||
if (!fu_redfish_request_patch(request,
|
||||
uri,
|
||||
builder,
|
||||
FU_REDFISH_REQUEST_PERFORM_FLAG_LOAD_JSON,
|
||||
error))
|
||||
return FALSE;
|
||||
fu_redfish_backend_set_password(data->backend, password_new);
|
||||
|
||||
/* success */
|
||||
return fu_plugin_set_secure_config_value(plugin, "Password", password_new, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_plugin_redfish_coldplug(FuPlugin *plugin, GError **error)
|
||||
{
|
||||
@ -30,10 +79,18 @@ fu_plugin_redfish_coldplug(FuPlugin *plugin, GError **error)
|
||||
|
||||
/* get the list of devices */
|
||||
if (!fu_backend_coldplug(FU_BACKEND(data->backend), &error_local)) {
|
||||
if (g_error_matches(error_local, FWUPD_ERROR, FWUPD_ERROR_AUTH_FAILED))
|
||||
fu_plugin_add_flag(plugin, FWUPD_PLUGIN_FLAG_AUTH_REQUIRED);
|
||||
g_propagate_error(error, g_steal_pointer(&error_local));
|
||||
return FALSE;
|
||||
/* did the user password expire? */
|
||||
if (g_error_matches(error_local, FWUPD_ERROR, FWUPD_ERROR_AUTH_EXPIRED)) {
|
||||
if (!fu_plugin_redfish_change_expired(plugin, error))
|
||||
return FALSE;
|
||||
if (!fu_backend_coldplug(FU_BACKEND(data->backend), error)) {
|
||||
fu_plugin_add_flag(plugin, FWUPD_PLUGIN_FLAG_AUTH_REQUIRED);
|
||||
return FALSE;
|
||||
}
|
||||
} else {
|
||||
g_propagate_error(error, g_steal_pointer(&error_local));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
devices = fu_backend_get_devices(FU_BACKEND(data->backend));
|
||||
for (guint i = 0; i < devices->len; i++) {
|
||||
@ -186,19 +243,6 @@ fu_redfish_plugin_discover_smbios_table(FuPlugin *plugin, GError **error)
|
||||
}
|
||||
|
||||
#ifdef HAVE_LINUX_IPMI_H
|
||||
static gchar *
|
||||
fu_common_generate_password(guint length)
|
||||
{
|
||||
GString *str = g_string_sized_new(length);
|
||||
|
||||
/* get a random password string */
|
||||
while (str->len < length) {
|
||||
gchar tmp = (gchar)g_random_int_range(0x0, 0xff);
|
||||
if (g_ascii_isalnum(tmp))
|
||||
g_string_append_c(str, tmp);
|
||||
}
|
||||
return g_string_free(str, FALSE);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_redfish_plugin_ipmi_create_user(FuPlugin *plugin, GError **error)
|
||||
@ -272,6 +316,8 @@ fu_redfish_plugin_ipmi_create_user(FuPlugin *plugin, GError **error)
|
||||
fu_redfish_backend_set_password(data->backend, password_new);
|
||||
|
||||
/* success */
|
||||
if (!fu_plugin_set_secure_config_value(plugin, "UserUri", uri, error))
|
||||
return FALSE;
|
||||
if (!fu_plugin_set_secure_config_value(plugin, "Username", username_fwupd, error))
|
||||
return FALSE;
|
||||
if (!fu_plugin_set_secure_config_value(plugin, "Password", password_new, error))
|
||||
|
@ -138,6 +138,8 @@ fu_redfish_request_load_json(FuRedfishRequest *self, GByteArray *buf, GError **e
|
||||
}
|
||||
if (g_strcmp0(id, "Base.1.8.AccessDenied") == 0)
|
||||
error_code = FWUPD_ERROR_AUTH_FAILED;
|
||||
else if (g_strcmp0(id, "Base.1.8.PasswordChangeRequired") == 0)
|
||||
error_code = FWUPD_ERROR_AUTH_EXPIRED;
|
||||
g_set_error_literal(error, FWUPD_ERROR, error_code, msg);
|
||||
return FALSE;
|
||||
}
|
||||
@ -244,7 +246,7 @@ fu_redfish_request_patch(FuRedfishRequest *self,
|
||||
json_generator_set_root(json_generator, json_root);
|
||||
json_generator_to_gstring(json_generator, str);
|
||||
if (g_getenv("FWUPD_REDFISH_VERBOSE") != NULL)
|
||||
g_debug("request: %s", str->str);
|
||||
g_debug("request to %s: %s", path, str->str);
|
||||
|
||||
/* patch */
|
||||
curl_easy_setopt(self->curl, CURLOPT_CUSTOMREQUEST, "PATCH");
|
||||
|
@ -59,6 +59,8 @@ install_data(['redfish.conf'],
|
||||
if get_option('tests')
|
||||
install_data(['tests/redfish-smbios.bin'],
|
||||
install_dir: join_paths(installed_test_datadir, 'tests'))
|
||||
install_data(['tests/redfish.conf'],
|
||||
install_dir: join_paths(installed_test_datadir, 'tests'))
|
||||
install_data(['tests/efi/efivars/RedfishIndications-16faa37e-4b6a-4891-9028-242de65a3b70'],
|
||||
install_dir: join_paths(installed_test_datadir, 'tests', 'efi', 'efivars'))
|
||||
install_data(['tests/efi/efivars/RedfishOSCredentials-16faa37e-4b6a-4891-9028-242de65a3b70'],
|
||||
|
Loading…
Reference in New Issue
Block a user