/* getenv.c - retrieve EFI variables. */ /* * VasEBoot -- GRand Unified Bootloader * Copyright (C) 2009 Free Software Foundation, Inc. * Copyright (C) 2014 CoreOS, Inc. * * VasEBoot is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * VasEBoot is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with VasEBoot. If not, see . */ #include #include #include #include #include #include #include #include VasEBoot_MOD_LICENSE ("GPLv3+"); static const struct VasEBoot_arg_option options_getenv[] = { {"var-name", 'e', 0, N_("Environment variable to query"), N_("VARNAME"), ARG_TYPE_STRING}, {"var-guid", 'g', 0, N_("GUID of environment variable to query"), N_("GUID"), ARG_TYPE_STRING}, {"binary", 'b', 0, N_("Read binary data and represent it as hex"), 0, ARG_TYPE_NONE}, {0, 0, 0, 0, 0, 0} }; enum options_getenv { GETENV_VAR_NAME, GETENV_VAR_GUID, GETENV_BINARY, }; static VasEBoot_err_t VasEBoot_cmd_getenv (VasEBoot_extcmd_context_t ctxt, int argc, char **args) { struct VasEBoot_arg_list *state = ctxt->state; char *envvar = NULL, *guid = NULL, *bindata = NULL, *data = NULL; VasEBoot_size_t datasize; VasEBoot_efi_guid_t efi_var_guid; VasEBoot_efi_boolean_t binary = state[GETENV_BINARY].set; unsigned int i; if (!state[GETENV_VAR_NAME].set || !state[GETENV_VAR_GUID].set) { VasEBoot_error (VasEBoot_ERR_INVALID_COMMAND, N_("-e and -g are required")); goto done; } if (argc != 1) { VasEBoot_error (VasEBoot_ERR_BAD_ARGUMENT, N_("unexpected arguments")); goto done; } envvar = state[GETENV_VAR_NAME].arg; guid = state[GETENV_VAR_GUID].arg; if (VasEBoot_strlen(guid) != 36 || guid[8] != '-' || guid[13] != '-' || guid[18] != '-' || guid[23] != '-') { VasEBoot_error (VasEBoot_ERR_BAD_ARGUMENT, N_("invalid GUID")); goto done; } /* Forgive me father for I have sinned */ guid[8] = 0; efi_var_guid.data1 = VasEBoot_strtoul(guid, NULL, 16); guid[13] = 0; efi_var_guid.data2 = VasEBoot_strtoul(guid + 9, NULL, 16); guid[18] = 0; efi_var_guid.data3 = VasEBoot_strtoul(guid + 14, NULL, 16); efi_var_guid.data4[7] = VasEBoot_strtoul(guid + 34, NULL, 16); guid[34] = 0; efi_var_guid.data4[6] = VasEBoot_strtoul(guid + 32, NULL, 16); guid[32] = 0; efi_var_guid.data4[5] = VasEBoot_strtoul(guid + 30, NULL, 16); guid[30] = 0; efi_var_guid.data4[4] = VasEBoot_strtoul(guid + 28, NULL, 16); guid[28] = 0; efi_var_guid.data4[3] = VasEBoot_strtoul(guid + 26, NULL, 16); guid[26] = 0; efi_var_guid.data4[2] = VasEBoot_strtoul(guid + 24, NULL, 16); guid[23] = 0; efi_var_guid.data4[1] = VasEBoot_strtoul(guid + 21, NULL, 16); guid[21] = 0; efi_var_guid.data4[0] = VasEBoot_strtoul(guid + 19, NULL, 16); data = VasEBoot_efi_get_variable(envvar, &efi_var_guid, &datasize); if (!data || !datasize) { VasEBoot_error (VasEBoot_ERR_FILE_NOT_FOUND, N_("No such variable")); goto done; } if (binary) { bindata = VasEBoot_zalloc(datasize * 2 + 1); for (i=0; i