summaryrefslogtreecommitdiff
path: root/futility/updater_archive.c
diff options
context:
space:
mode:
Diffstat (limited to 'futility/updater_archive.c')
-rw-r--r--futility/updater_archive.c96
1 files changed, 89 insertions, 7 deletions
diff --git a/futility/updater_archive.c b/futility/updater_archive.c
index e08f736a..7ce210f3 100644
--- a/futility/updater_archive.c
+++ b/futility/updater_archive.c
@@ -65,6 +65,8 @@ static const char * const SETVARS_IMAGE_MAIN = "IMAGE_MAIN",
* const DIR_KEYSET = "keyset",
* const DIR_MODELS = "models",
* const DEFAULT_MODEL_NAME = "default",
+ * const VPD_WHITELABEL_TAG = "whitelabel_tag",
+ * const VPD_CUSTOMIZATION_ID = "customization_id",
* const ENV_VAR_MODEL_DIR = "${MODEL_DIR}",
* const PATH_STARTSWITH_KEYSET = "keyset/",
* const PATH_ENDSWITH_SERVARS = "/setvars.sh";
@@ -365,16 +367,16 @@ int archive_read_file(struct archive *ar, const char *fname,
* -- End of archive implementations --
*/
-/* Utility function to convert a string to all lowercase. */
-static void str_tolower(char *s)
+/* Utility function to convert a string. */
+static void str_convert(char *s, int (*convert)(int c))
{
int c;
for (; *s; s++) {
c = *s;
- if (!isascii(c) || !isalpha(c))
+ if (!isascii(c))
continue;
- *s = tolower(c);
+ *s = convert(c);
}
}
@@ -393,6 +395,23 @@ static int str_startswith(const char *name, const char *pattern)
return strncmp(name, pattern, strlen(pattern)) == 0;
}
+/* Returns the VPD value by given key name, or NULL on error (or no value). */
+static char *vpd_get_value(const char *fpath, const char *key)
+{
+ char *command, *result;
+
+ assert(fpath);
+ ASPRINTF(&command, "vpd -g %s -f %s 2>/dev/null", key, fpath);
+ result = host_shell(command);
+ free(command);
+
+ if (result && !*result) {
+ free(result);
+ result = NULL;
+ }
+ return result;
+}
+
/*
* Reads and parses a setvars type file from archive, then stores into config.
* Returns 0 on success (at least one entry found), otherwise failure.
@@ -442,9 +461,11 @@ static int model_config_parse_setvars_file(
cfg->ec_image = strdup(v);
else if (strcmp(k, SETVARS_IMAGE_PD) == 0)
cfg->pd_image = strdup(v);
- else if (strcmp(k, SETVARS_SIGNATURE_ID) == 0)
+ else if (strcmp(k, SETVARS_SIGNATURE_ID) == 0) {
cfg->signature_id = strdup(v);
- else
+ if (str_startswith(v, SIG_ID_IN_VPD_PREFIX))
+ cfg->is_white_label = 1;
+ } else
found_valid = 0;
free(expand_path);
valid += found_valid;
@@ -690,6 +711,65 @@ const struct model_config *manifest_find_model(const struct manifest *manifest,
}
/*
+ * Applies white label information to an existing model configuration.
+ * Collects signature ID information from either parameter signature_id or
+ * image file (via VPD) and updates model.patches for key files.
+ * Returns 0 on success, otherwise failure.
+ */
+int model_apply_white_label(
+ struct model_config *model,
+ struct archive *archive,
+ const char *signature_id,
+ const char *image)
+{
+ char *sig_id = NULL;
+ int r = 0;
+
+ if (!signature_id) {
+ int remove_dash = 0, prefix_model = model->signature_id ? 1 : 0;
+ char *wl_tag = vpd_get_value(image, VPD_WHITELABEL_TAG);
+
+ if (!wl_tag) {
+ if (model->signature_id)
+ return -1;
+ wl_tag = vpd_get_value(image, VPD_CUSTOMIZATION_ID);
+ /* customization_id in format LOEM[-VARIANT]. */
+ remove_dash = 1;
+
+ }
+ if (!wl_tag)
+ return 1;
+
+ if (remove_dash) {
+ char *dash = strchr(wl_tag, '-');
+ if (dash)
+ *dash = '\0';
+ }
+ if (!prefix_model)
+ str_convert(wl_tag, toupper);
+
+ sig_id = wl_tag;
+ if (prefix_model)
+ ASPRINTF(&sig_id, "%s-%s", model->name, wl_tag);
+ else
+ wl_tag = NULL;
+ free(wl_tag);
+ signature_id = sig_id;
+ }
+
+ DEBUG("Find white label patches by signature ID: '%s'.", signature_id);
+ find_patches_for_model(model, archive, signature_id);
+ if (!model->patches.rootkey) {
+ ERROR("No keys found for signature_id: '%s'", signature_id);
+ r = 1;
+ } else {
+ printf("Applied for white label: %s\n", signature_id);
+ }
+ free(sig_id);
+ return r;
+}
+
+/*
* Creates a new manifest object by scanning files in archive.
* Returns the manifest on success, otherwise NULL for failure.
*/
@@ -720,13 +800,15 @@ struct manifest *new_manifest_from_archive(struct archive *archive)
if (strtok(image.ro_version, "_"))
token = strtok(NULL, ".");
if (token && *token) {
- str_tolower(token);
+ str_convert(token, tolower);
model.name = strdup(token);
}
free_firmware_image(&image);
}
if (!model.name)
model.name = strdup(DEFAULT_MODEL_NAME);
+ if (manifest.has_keyset)
+ model.is_white_label = 1;
manifest_add_model(&manifest, &model);
manifest.default_model = manifest.num - 1;
}