From bc678d18f95fa6768fe3d66e122659d7270fbe2751886b524b706502815022e5 Mon Sep 17 00:00:00 2001 From: Gary Ching-Pang Lin Date: Mon, 15 Apr 2013 04:32:40 +0000 Subject: [PATCH] Accepting request 164014 from home:gary_lin:branches:Base:System bnc#809215: improve the error messages bnc#809703: remove the key from the pending request if necessary OBS-URL: https://build.opensuse.org/request/show/164014 OBS-URL: https://build.opensuse.org/package/show/Base:System/mokutil?expand=0&rev=8 --- mokutil-bnc809215-improve-wording.patch | 105 ++++++ mokutil-bnc809703-check-pending-request.patch | 340 ++++++++++++++++++ mokutil.changes | 8 + mokutil.spec | 6 + 4 files changed, 459 insertions(+) create mode 100644 mokutil-bnc809215-improve-wording.patch create mode 100644 mokutil-bnc809703-check-pending-request.patch diff --git a/mokutil-bnc809215-improve-wording.patch b/mokutil-bnc809215-improve-wording.patch new file mode 100644 index 0000000..870637e --- /dev/null +++ b/mokutil-bnc809215-improve-wording.patch @@ -0,0 +1,105 @@ +commit 08e7fbbfec644406b5f6f3ce787444bc5e2c4b3d +Author: Gary Ching-Pang Lin +Date: Fri Mar 29 12:12:00 2013 +0800 + + Make the error message more understandable + +diff --git a/src/efilib.c b/src/efilib.c +index cb1aca6..1b72cd9 100644 +--- a/src/efilib.c ++++ b/src/efilib.c +@@ -5,6 +5,7 @@ + #include + #include + #include ++#include + #include "efi.h" + + #define SYSFS_DIR_EFI_VARS "/sys/firmware/efi/efivars" +@@ -95,7 +96,9 @@ read_variable (efi_variable_t *var) + snprintf (filename, PATH_MAX-1, "%s/%s", SYSFS_DIR_EFI_VARS, name); + fd = open (filename, O_RDONLY); + if (fd == -1) { +- return EFI_NOT_FOUND; ++ if (errno == ENOENT) ++ return EFI_NOT_FOUND; ++ return EFI_INVALID_PARAMETER; + } + + if (fstat (fd, &buf) != 0) { +diff --git a/src/mokutil.c b/src/mokutil.c +index 27ebf09..3f89db2 100644 +--- a/src/mokutil.c ++++ b/src/mokutil.c +@@ -236,14 +236,20 @@ static int + list_enrolled_keys () + { + efi_variable_t var; ++ efi_status_t status; + int ret; + + memset (&var, 0, sizeof(var)); + var.VariableName = "MokListRT"; +- + var.VendorGuid = SHIM_LOCK_GUID; + +- if (read_variable (&var) != EFI_SUCCESS) { ++ status = read_variable (&var); ++ if (status != EFI_SUCCESS) { ++ if (status == EFI_NOT_FOUND) { ++ printf ("MokListRT is empty\n"); ++ return 0; ++ } ++ + fprintf (stderr, "Failed to read MokListRT\n"); + return -1; + } +@@ -258,14 +264,20 @@ static int + list_new_keys () + { + efi_variable_t var; ++ efi_status_t status; + int ret; + + memset (&var, 0, sizeof(var)); + var.VariableName = "MokNew"; +- + var.VendorGuid = SHIM_LOCK_GUID; + +- if (read_variable (&var) != EFI_SUCCESS) { ++ status = read_variable (&var); ++ if (status != EFI_SUCCESS) { ++ if (status == EFI_NOT_FOUND) { ++ printf ("No MOK new key request\n"); ++ return 0; ++ } ++ + fprintf (stderr, "Failed to read MokNew\n"); + return -1; + } +@@ -812,6 +824,7 @@ static int + export_moks () + { + efi_variable_t var; ++ efi_status_t status; + char filename[PATH_MAX]; + uint32_t mok_num; + MokListNode *list; +@@ -822,10 +835,15 @@ export_moks () + + memset (&var, 0, sizeof(var)); + var.VariableName = "MokListRT"; +- + var.VendorGuid = SHIM_LOCK_GUID; + +- if (read_variable (&var) != EFI_SUCCESS) { ++ status = read_variable (&var); ++ if (status != EFI_SUCCESS) { ++ if (status == EFI_NOT_FOUND) { ++ printf ("MokListRT is empty\n"); ++ return 0; ++ } ++ + fprintf (stderr, "Failed to read MokListRT\n"); + return -1; + } diff --git a/mokutil-bnc809703-check-pending-request.patch b/mokutil-bnc809703-check-pending-request.patch new file mode 100644 index 0000000..d60e670 --- /dev/null +++ b/mokutil-bnc809703-check-pending-request.patch @@ -0,0 +1,340 @@ +From 9a114bb26e81f3b2764d84b8a6f5b9bd2e1528de Mon Sep 17 00:00:00 2001 +From: Gary Ching-Pang Lin +Date: Fri, 29 Mar 2013 18:00:55 +0800 +Subject: [PATCH 1/3] Delete key from the pending request + +--- + src/mokutil.c | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---- + 1 file changed, 108 insertions(+), 8 deletions(-) + +diff --git a/src/mokutil.c b/src/mokutil.c +index 3f89db2..01a1b79 100644 +--- a/src/mokutil.c ++++ b/src/mokutil.c +@@ -49,8 +49,9 @@ EFI_GUID (0x605dab50, 0xe046, 0x4300, 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, + #define SETTINGS_LEN (DEFAULT_SALT_SIZE*2) + + typedef struct { +- uint32_t mok_size; +- void *mok; ++ EFI_SIGNATURE_LIST *header; ++ uint32_t mok_size; ++ void *mok; + } MokListNode; + + typedef struct { +@@ -154,8 +155,9 @@ build_mok_list (void *data, unsigned long data_size, uint32_t *mok_num) + return NULL; + } + ++ list[count].header = CertList; + list[count].mok_size = CertList->SignatureSize - sizeof(efi_guid_t); +- list[count].mok = (void *)Cert->SignatureData; ++ list[count].mok = (void *)Cert->SignatureData; + + count++; + dbsize -= CertList->SignatureListSize; +@@ -233,6 +235,74 @@ list_keys (efi_variable_t *var) + } + + static int ++delete_key_from_list (void *mok, uint32_t mok_size, ++ const char *var_name, efi_guid_t guid) ++{ ++ efi_variable_t var; ++ MokListNode *list; ++ uint32_t mok_num, total, remain; ++ void *ptr, *data = NULL; ++ int i, del_ind, ret = 0; ++ ++ if (!var_name || !mok || mok_size == 0) ++ return 0; ++ ++ memset (&var, 0, sizeof(var)); ++ var.VariableName = var_name; ++ var.VendorGuid = guid; ++ ++ if (read_variable (&var) != EFI_SUCCESS) ++ return 0; ++ ++ total = var.DataSize; ++ ++ list = build_mok_list (var.Data, var.DataSize, &mok_num); ++ if (list == NULL) ++ goto done; ++ ++ for (i = 0; i < mok_num; i++) { ++ if (list[i].mok_size != mok_size) ++ continue; ++ ++ if (memcmp (list[i].mok, mok, mok_size) == 0) { ++ /* Remove this key */ ++ del_ind = i; ++ data = (void *)list[i].header; ++ ptr = data + list[i].header->SignatureListSize; ++ total -= list[i].header->SignatureListSize; ++ break; ++ } ++ } ++ ++ /* the key is not in this list */ ++ if (data == NULL) ++ return 0; ++ ++ /* Move the rest of the keys */ ++ remain = 0; ++ for (i = del_ind + 1; i < mok_num; i++) ++ remain += list[i].header->SignatureListSize; ++ if (remain > 0) ++ memmove (data, ptr, remain); ++ ++ var.DataSize = total; ++ var.Attributes = EFI_VARIABLE_NON_VOLATILE ++ | EFI_VARIABLE_BOOTSERVICE_ACCESS ++ | EFI_VARIABLE_RUNTIME_ACCESS; ++ ++ if (edit_protected_variable (&var) != EFI_SUCCESS) { ++ fprintf (stderr, "Failed to write %s\n", var_name); ++ goto done; ++ } ++ ++ ret = 1; ++done: ++ free (var.Data); ++ ++ return ret; ++} ++ ++static int + list_enrolled_keys () + { + efi_variable_t var; +@@ -658,6 +728,34 @@ is_valid_request (void *mok, uint32_t mok_size, uint8_t import) + } + + static int ++in_pending_request (void *mok, uint32_t mok_size, uint8_t import) ++{ ++ efi_variable_t authvar; ++ const char *var_name = import ? "MokDel" : "MokNew"; ++ ++ if (!mok || mok_size == 0) ++ return 0; ++ ++ memset (&authvar, 0, sizeof(authvar)); ++ authvar.VariableName = import ? "MokDelAuth" : "MokAuth"; ++ authvar.VendorGuid = SHIM_LOCK_GUID; ++ ++ if (read_variable (&authvar) != EFI_SUCCESS) { ++ return 0; ++ } ++ ++ free (authvar.Data); ++ /* Check if the password hash is in the old format */ ++ if (authvar.DataSize == SHA256_DIGEST_LENGTH) ++ return 0; ++ ++ if (delete_key_from_list (mok, mok_size, var_name, SHIM_LOCK_GUID)) ++ return 1; ++ ++ return 0; ++} ++ ++static int + issue_mok_request (char **files, uint32_t total, uint8_t import, + const char *hash_file, const int root_pw) + { +@@ -678,10 +776,7 @@ issue_mok_request (char **files, uint32_t total, uint8_t import, + if (!files) + return -1; + +- if (import) +- req_name = "MokNew"; +- else +- req_name = "MokDel"; ++ req_name = import ? "MokNew" : "MokDel"; + + sizes = malloc (total * sizeof(uint32_t)); + +@@ -692,6 +787,7 @@ issue_mok_request (char **files, uint32_t total, uint8_t import, + goto error; + } + ++ /* get the sizes of the key files */ + for (i = 0; i < total; i++) { + if (stat (files[i], &buf) != 0) { + fprintf (stderr, "Failed to get file status, %s\n", +@@ -752,6 +848,10 @@ issue_mok_request (char **files, uint32_t total, uint8_t import, + if (is_valid_request (ptr, sizes[i], import)) { + ptr += sizes[i]; + real_size += sizes[i] + sizeof(EFI_SIGNATURE_LIST) + sizeof(efi_guid_t); ++ } else if (in_pending_request (ptr, sizes[i], import)) { ++ printf ("Removed %s from %s\n", files[i], import ? "MokDel" : "MokNew"); ++ ++ ptr -= sizeof(EFI_SIGNATURE_LIST) + sizeof(efi_guid_t); + } else { + printf ("Skip %s\n", files[i]); + ptr -= sizeof(EFI_SIGNATURE_LIST) + sizeof(efi_guid_t); +@@ -760,7 +860,7 @@ issue_mok_request (char **files, uint32_t total, uint8_t import, + close (fd); + } + +- /* All keys are enrolled, nothing to do here... */ ++ /* All keys are in the list, nothing to do here... */ + if (real_size == 0) { + ret = 0; + goto error; +-- +1.8.1.4 + + +From d00c50c0eb73c27b1c49d8d947b99e24a4da4a66 Mon Sep 17 00:00:00 2001 +From: Gary Ching-Pang Lin +Date: Fri, 29 Mar 2013 14:21:00 +0800 +Subject: [PATCH 2/3] Remove the unnecessary command flags + +--- + src/mokutil.c | 47 ++++++++++++++++++++++------------------------- + 1 file changed, 22 insertions(+), 25 deletions(-) + +diff --git a/src/mokutil.c b/src/mokutil.c +index 01a1b79..6c3a135 100644 +--- a/src/mokutil.c ++++ b/src/mokutil.c +@@ -40,9 +40,7 @@ EFI_GUID (0x605dab50, 0xe046, 0x4300, 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, + #define SB_STATE 0x800 + #define TEST_KEY 0x1000 + #define RESET 0x2000 +-#define HASH_FILE 0x4000 +-#define GENERATE_PW_HASH 0x8000 +-#define ROOT_PW 0x10000 ++#define GENERATE_PW_HASH 0x4000 + + #define DEFAULT_CRYPT_METHOD SHA512_BASED + #define DEFAULT_SALT_SIZE SHA512_SALT_MAX +@@ -1247,6 +1245,7 @@ main (int argc, char *argv[]) + const char *option; + int c, i, f_ind, total = 0; + unsigned int command = 0; ++ int use_root_pw = 0; + int ret = -1; + + while (1) { +@@ -1329,7 +1328,6 @@ main (int argc, char *argv[]) + case 'f': + hash_file = strdup (optarg); + +- command |= HASH_FILE; + break; + case 'g': + if (optarg) +@@ -1341,7 +1339,7 @@ main (int argc, char *argv[]) + command |= PASSWORD; + break; + case 'P': +- command |= ROOT_PW; ++ use_root_pw = 1; + break; + case 't': + key_file = strdup (optarg); +@@ -1360,6 +1358,9 @@ main (int argc, char *argv[]) + } + } + ++ if (hash_file && use_root_pw) ++ command |= HELP; ++ + switch (command) { + case LIST_ENROLLED: + ret = list_enrolled_keys (); +@@ -1368,18 +1369,16 @@ main (int argc, char *argv[]) + ret = list_new_keys (); + break; + case IMPORT: +- case IMPORT | HASH_FILE: +- ret = import_moks (files, total, hash_file, 0); +- break; +- case IMPORT | ROOT_PW: +- ret = import_moks (files, total, NULL, 1); ++ if (use_root_pw) ++ ret = import_moks (files, total, NULL, 1); ++ else ++ ret = import_moks (files, total, hash_file, 0); + break; + case DELETE: +- case DELETE | HASH_FILE: +- ret = delete_moks (files, total, hash_file, 0); +- break; +- case DELETE | ROOT_PW: +- ret = delete_moks (files, total, NULL, 1); ++ if (use_root_pw) ++ ret = delete_moks (files, total, NULL, 1); ++ else ++ ret = delete_moks (files, total, hash_file, 0); + break; + case REVOKE_IMPORT: + ret = revoke_request (1); +@@ -1391,11 +1390,10 @@ main (int argc, char *argv[]) + ret = export_moks (); + break; + case PASSWORD: +- case PASSWORD | HASH_FILE: +- ret = set_password (hash_file, 0); +- break; +- case PASSWORD | ROOT_PW: +- ret = set_password (NULL, 1); ++ if (use_root_pw) ++ ret = set_password (NULL, 1); ++ else ++ ret = set_password (hash_file, 0); + break; + case DISABLE_VALIDATION: + ret = disable_validation (); +@@ -1410,11 +1408,10 @@ main (int argc, char *argv[]) + ret = test_key (key_file); + break; + case RESET: +- case RESET | HASH_FILE: +- ret = reset_moks (hash_file, 0); +- break; +- case RESET | ROOT_PW: +- ret = reset_moks (NULL, 1); ++ if (use_root_pw) ++ ret = reset_moks (NULL, 1); ++ else ++ ret = reset_moks (hash_file, 0); + break; + case GENERATE_PW_HASH: + ret = generate_pw_hash (input_pw); +-- +1.8.1.4 + + +From 3c3725784cd31d867443675cb5aa6698b952ac2b Mon Sep 17 00:00:00 2001 +From: Gary Ching-Pang Lin +Date: Tue, 2 Apr 2013 11:29:01 +0800 +Subject: [PATCH 3/3] Show help if there is no key to be imported/deleted + +--- + src/mokutil.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/src/mokutil.c b/src/mokutil.c +index 6c3a135..58566f9 100644 +--- a/src/mokutil.c ++++ b/src/mokutil.c +@@ -1317,6 +1317,11 @@ main (int argc, char *argv[]) + total++; + } + ++ if (total == 0) { ++ command |= HELP; ++ break; ++ } ++ + files = malloc (total * sizeof (char *)); + for (i = 0; i < total; i++) { + f_ind = i + optind - 1; +-- +1.8.1.4 + diff --git a/mokutil.changes b/mokutil.changes index 98e6689..86e9262 100644 --- a/mokutil.changes +++ b/mokutil.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Tue Apr 2 04:43:59 UTC 2013 - glin@suse.com + +- Add mokutil-bnc809215-improve-wording.patch to make the messages + understandable (bnc#809215) +- Add mokutil-bnc809703-check-pending-request.patch to remove the + key from the pending request if necessary (bnc#809703) + ------------------------------------------------------------------- Wed Jan 30 08:00:22 UTC 2013 - glin@suse.com diff --git a/mokutil.spec b/mokutil.spec index cbe3d52..4d04c14 100644 --- a/mokutil.spec +++ b/mokutil.spec @@ -40,6 +40,10 @@ Patch6: mokutil-support-crypt-hash-methods.patch Patch7: mokutil-update-man-page.patch # PATCH-FIX-UPSTREAM mokutil-lcrypt-ldflag.patch glin@suse.com -- Add -lcrpyt correctly Patch8: mokutil-lcrypt-ldflag.patch +# PATCH-FIX-UPSTREAM mokutil-bnc809215-improve-wording.patch bnc#809215 glin@suse.com -- Improve the wording of error messages +Patch9: mokutil-bnc809215-improve-wording.patch +# PATCH-FIX-UPSTREAM mokutil-bnc809703-check-pending-request.patch bnc#809703 glin@suse.com -- Remove the key from the pending requests if necessary +Patch10: mokutil-bnc809703-check-pending-request.patch BuildRequires: autoconf BuildRequires: automake BuildRequires: libopenssl-devel >= 0.9.8 @@ -67,6 +71,8 @@ Authors: %patch6 -p1 %patch7 -p1 %patch8 -p1 +%patch9 -p1 +%patch10 -p1 %build autoreconf -i -f