From 8061f0324183684a5620e0e6131819351cea60f3 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Fri, 19 Jan 2024 12:29:38 +0000 Subject: [PATCH 01/79] Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild From 9c1207e0eb3493430fe6e5fe181c8f43eff3dd8a Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Mon, 22 Jan 2024 22:49:36 +0000 Subject: [PATCH 02/79] Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild From e1bb15842510275935af959714be82f1067e761f Mon Sep 17 00:00:00 2001 From: Marius Schwarz Date: Thu, 4 Jul 2024 08:48:59 +0200 Subject: [PATCH 03/79] Call Init before the argument parser So initialized variables are later overriden by the arguments Signed-off-by: Nicolas Chauvet --- akmods | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/akmods b/akmods index af14ee8..0e3fee5 100644 --- a/akmods +++ b/akmods @@ -1,4 +1,4 @@ -#!/bin/bash - +#!/usr/bin/bash - ######################################################################## # # akmods - Rebuilds and install akmod RPMs @@ -497,6 +497,9 @@ myprog_help () echo " --akmod -- build and install only akmod " } +# Call INIT to INIT the defaults, that are overwritten in the argument parser! +init + # first parse command line options while [ "${1}" ] ; do @@ -589,9 +592,6 @@ while [ "${1}" ] ; do esac done -# sanity checks -init - # go for kernel in ${kernels} ; do check_kmods ${kernel} From 08e2a487649bd25718f0eb894b3ef792546b6a03 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 11 Jun 2024 19:42:10 +0000 Subject: [PATCH 04/79] Fix intel-ipu6-kmod installation with kernel >= 6.10 The intel-ipu6 kmod contains multiple .ko files. The main intel_ipu6.ko as well as separate modules for the CSI-2 receiver (intel_ipu6_isys.ko) and the ISP (intel_ipu6_psys.ko) functions. The intel_ipu6.ko and intel_ipu6_isys.ko modules have been mainlined in kernel 6.10. But the ISP (intel_ipu6_psys.ko) support has not been mainlined and this will not be mainlined for a long time to come. So the intel-ipu6 kmod is still useful for users to have. But now that intel_ipu6.ko is part of the mainline kernel, "modinfo -n intel-ipu6" will return a path to the version under /lib/modules/$kver/kernel/ when the kmod is not installed yet causing the check for no kmod being installed yet: # kmod present, even with weak-modules? if [[ ! -n "${kmodpackage_file}" ]] && [[ ! -d /lib/modules/${this_kernelver}/extra/${this_kmodname}/ ]] ; then to fail, which in turn causes the version check to fail with: "Warning: Could not determine what package owns /lib/modules/$kver/extra/intel-ipu6/" Add a new special case for when "modinfo -n $kmodname" returns a path under /lib/modules/$kver/kernel/ to fix this. --- akmods | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/akmods b/akmods index 0e3fee5..71f4d93 100644 --- a/akmods +++ b/akmods @@ -370,6 +370,14 @@ check_kmod_up2date() return 1 fi + # special case where part of the kmod is mainlined using $this_kmodname + # making $kmodpackage_file non zero when the kmod is not install yet + if [[ "${kmodpackage_file}" == "/lib/modules/${this_kernelver}/"* ]] && \ + [[ ! -d /lib/modules/${this_kernelver}/extra/${this_kmodname}/ ]] ; then + # build it + return 1 + fi + # kmod up2date? # Weak module symlink case if [ -n "${kmodpackage_file}" ] && [ -h "${kmodpackage_file}" ] && $(echo "${kmodpackage_file}" | grep -q "weak-updates") ; then From 9caa233dee128715c47259058e838a7058382508 Mon Sep 17 00:00:00 2001 From: Nicolas Chauvet Date: Thu, 4 Jul 2024 22:22:49 +0200 Subject: [PATCH 05/79] akmods release 0.5.9 --- akmods | 2 +- akmods.spec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/akmods b/akmods index 71f4d93..177c0a2 100644 --- a/akmods +++ b/akmods @@ -37,7 +37,7 @@ # global vars myprog="akmods" -myver="0.5.8" +myver="0.5.9" kmodlogfile= continue_line="" tmpdir= diff --git a/akmods.spec b/akmods.spec index 226e7da..3e7035b 100644 --- a/akmods.spec +++ b/akmods.spec @@ -1,5 +1,5 @@ Name: akmods -Version: 0.5.8 +Version: 0.5.9 Release: %autorelease Summary: Automatic kmods build and install tool From 7a7ddff3ea061c6a396d82e38b7059d80dc0d0fa Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 17 Jul 2024 16:45:59 +0000 Subject: [PATCH 06/79] Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild From 9bbb95488246e935705ba9573c5f1776045caa4a Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Mon, 19 Aug 2024 12:27:22 +0100 Subject: [PATCH 07/79] Fix bug URLs in man page --- akmods.h2m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/akmods.h2m b/akmods.h2m index 22f3e55..214d28d 100644 --- a/akmods.h2m +++ b/akmods.h2m @@ -1,9 +1,9 @@ [BUGS] -https://bugzilla.rpmfusion.org/buglist.cgi?product=Fedora&component=akmods&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED +https://bugz.fedoraproject.org/akmods [REPORTING BUGS] Submit a bug against the akmods component at: .br -https://bugzilla.rpmfusion.org/enter_bug.cgi?product=Fedora +https://bugzilla.redhat.com/enter_bug.cgi?product=Fedora [AUTHOR] Thorsten Leemhuis [MAINTAINER] From e8b284bcdbfe1a6cd4562da74966de874db43ecf Mon Sep 17 00:00:00 2001 From: Nicolas Chauvet Date: Fri, 23 Aug 2024 12:04:04 +0200 Subject: [PATCH 08/79] Drop older rhel cases --- akmods.spec | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/akmods.spec b/akmods.spec index 3e7035b..262da7c 100644 --- a/akmods.spec +++ b/akmods.spec @@ -52,11 +52,7 @@ Requires: gzip make sed tar unzip util-linux rpm-build # On EL, kABI list was renamed %if 0%{?rhel} -%if 0%{?rhel} >= 8 -Requires: (kernel-abi-stablelists if kernel) -%else -Requires: kernel-abi-whitelists -%endif +Requires: (kernel-abi-stablelists if kernel-core) %endif %if 0%{?fedora} || 0%{?rhel} > 7 From cb8200fc744b821310f6c8995b6d9722c7972803 Mon Sep 17 00:00:00 2001 From: Nicolas Chauvet Date: Fri, 23 Aug 2024 12:08:24 +0200 Subject: [PATCH 09/79] Drop older rhel and use -core --- akmods.spec | 23 +++-------------------- 1 file changed, 3 insertions(+), 20 deletions(-) diff --git a/akmods.spec b/akmods.spec index 262da7c..c0376a7 100644 --- a/akmods.spec +++ b/akmods.spec @@ -55,35 +55,18 @@ Requires: gzip make sed tar unzip util-linux rpm-build Requires: (kernel-abi-stablelists if kernel-core) %endif -%if 0%{?fedora} || 0%{?rhel} > 7 # We use a virtual provide that would match either # kernel-devel or kernel-PAE-devel Requires: kernel-devel-uname-r # kernel-devel-matched enforces the same kernel version as the -devel -%if 0%{?fedora} >= 36 || 0%{?rhel} >= 9 +%if 0%{?fedora} || 0%{?rhel} >= 9 Requires: (kernel-debug-devel-matched if kernel-debug-core) Requires: (kernel-devel-matched if kernel-core) -%ifarch %{arm} -Requires: (kernel-lpae-devel-matched if kernel-lpae-core) -%endif %else -Suggests: (kernel-debug-devel if kernel-debug) -Suggests: (kernel-devel if kernel) -%ifarch %{arm} -Suggests: (kernel-lpae-devel if kernel-lpae) -%endif -%endif -%ifarch %{ix86} -Suggests: (kernel-PAE-devel if kernel-PAE) -Suggests: (kernel-PAEdebug-devel if kernel-PAEdebug) -# Theses are from planetccrma-core or rhel-7-server-rt-rpms -Suggests: (kernel-rtPAE-devel if kernel-rtPAE) +Suggests: (kernel-debug-devel if kernel-debug-core) +Suggests: (kernel-devel if kernel-core) %endif Suggests: (kernel-rt-devel if kernel-rt) -%else -# There is no much variant there, so using a sane default -Requires: kernel-devel -%endif # we create a special user that used by akmods to build kmod packages Requires(pre): shadow-utils From 09953db160434babef64cdc5de642cc236ee6033 Mon Sep 17 00:00:00 2001 From: Nicolas Chauvet Date: Fri, 23 Aug 2024 12:10:00 +0200 Subject: [PATCH 10/79] Switch to use sdubby alternatives to grubby --- akmods.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/akmods.spec b/akmods.spec index c0376a7..cd58bcd 100644 --- a/akmods.spec +++ b/akmods.spec @@ -82,7 +82,7 @@ Requires: pkgconfig(libelf) # We need grubby or systemd-boot to know the default kernel # On EL7 assumes grubby is there by default - rhbz#2124086 %if 0%{?fedora} || 0%{?rhel} > 7 -Requires: (grubby or systemd-boot) +Requires: (grubby or sdubby) %endif %description From b7fda608ca2bc83c2695e7cf8c3313f8eb905d7b Mon Sep 17 00:00:00 2001 From: Nicolas Chauvet Date: Fri, 23 Aug 2024 12:34:25 +0200 Subject: [PATCH 11/79] Revert "Call Init before the argument parser" This reverts commit e1bb15842510275935af959714be82f1067e761f. This is because init assumes root permissions before proceeding. Just move the needed functions out --- akmods | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/akmods b/akmods index 177c0a2..56189e2 100644 --- a/akmods +++ b/akmods @@ -505,9 +505,6 @@ myprog_help () echo " --akmod -- build and install only akmod " } -# Call INIT to INIT the defaults, that are overwritten in the argument parser! -init - # first parse command line options while [ "${1}" ] ; do @@ -600,6 +597,9 @@ while [ "${1}" ] ; do esac done +# sanity checks +init + # go for kernel in ${kernels} ; do check_kmods ${kernel} From 1b5754dd1a6d66ddcd9849716e2ca4c7682fd622 Mon Sep 17 00:00:00 2001 From: Nicolas Chauvet Date: Fri, 23 Aug 2024 14:21:44 +0200 Subject: [PATCH 12/79] Only check for default_kernel is no value - rhbz#2293047 --- akmods | 86 ++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 53 insertions(+), 33 deletions(-) diff --git a/akmods b/akmods index 56189e2..d83d033 100644 --- a/akmods +++ b/akmods @@ -185,27 +185,6 @@ init () } fi - # ensure to build for grub or systemd-boot default kernel - # - # IMPORTANT: "bootctl is-installed" check that systemd-boot is installed only. - # It doesn't check if systemd-boot is the default loader. - # So we assume grubby results if available - if [ ! -h /usr/sbin/grubby ] && command -v grubby >/dev/null 2>&1 ; then - default_kernel=$(grubby --default-kernel | sed -e 's/^.*vmlinuz-//') - elif bootctl is-installed >/dev/null 2>&1 ; then - # Leave jq as optional - isDefault requires systemd 253 - if command -v jq >/dev/null ; then - default_kernel="$(bootctl list --json=short | jq -r '.[] | select(.isDefault).version')" - fi - else # They use neither systemd-boot nor grub2 - echo -n "Unable to figure out the default kernel" >&2 - echo_warning ; echo - default_kernel="" - fi - if ! $(echo "${kernels}" | grep -q "${default_kernel}") ; then - kernels="${kernels} ${default_kernel}" - fi - # needs root permissions if [[ ! -w /var ]] ; then echo -n "Needs to run as root to be able to install rpms." >&2 @@ -250,6 +229,51 @@ init () flock -w 900 99 } + +check_kernel_devel() +{ + if [[ ! -r /usr/src/kernels/"${1}"/Makefile ]] && \ + [[ ! -r /lib/modules/"${1}"/build/Makefile ]] ; then + echo "Could not find files needed to compile modules for ${1}" + echo "Are the development files for kernel ${1} or the appropriate kernel-devel package installed?" + exit 1 + elif [[ -r /usr/src/kernels/"${1}"/Makefile ]] && \ + [[ ! -d /lib/modules/"${1}" ]] ; then + # this is a red hat / fedora kernel-devel package, but the kernel for it is not installed + # kmodtool would add a dep on that kernel when building; thus when we'd try to install the + # rpms we'd run into a missing-dep problem. Thus we prevent that case + echo "Kernel ${1} not installed" + exit 1 + fi +} + +check_default_kernel() +{ + # Ensure to build for grub or systemd-boot default kernel + # + # IMPORTANT: "bootctl is-installed" check that systemd-boot is installed only. + # It doesn't check if systemd-boot is the default loader. + # So we assume grubby results if available + if [ ! -h /usr/sbin/grubby ] && command -v grubby >/dev/null 2>&1 ; then + default_kernel=$(grubby --default-kernel | sed -e 's/^.*vmlinuz-//') + elif bootctl is-installed >/dev/null 2>&1 ; then + # Leave jq as optional - isDefault requires systemd 253 + if command -v jq >/dev/null ; then + default_kernel="$(bootctl list --json=short | jq -r '.[] | select(.isDefault).version')" + fi + else # They use neither systemd-boot nor grub2 + echo -n "Unable to figure out the default kernel" >&2 + echo_warning ; echo + default_kernel="" + fi + + check_kernel_devel "${default_kernel}" + + if ! $(echo "${kernels}" | grep -q "${default_kernel}") ; then + kernels="${kernels} ${default_kernel}" + fi +} + buildinstall_kmod() { local this_kernelver=${1} @@ -514,19 +538,10 @@ while [ "${1}" ] ; do if [[ ! -n "${1}" ]] ; then echo "ERROR: Please provide the kernel-version to build for together with --kernel" >&2 exit 1 - elif [[ ! -r /usr/src/kernels/"${1}"/Makefile ]] && \ - [[ ! -r /lib/modules/"${1}"/build/Makefile ]] ; then - echo "Could not find files needed to compile modules for ${1}" - echo "Are the development files for kernel ${1} or the appropriate kernel-devel package installed?" - exit 1 - elif [[ -r /usr/src/kernels/"${1}"/Makefile ]] && \ - [[ ! -d /lib/modules/"${1}" ]] ; then - # this is a red hat / fedora kernel-devel package, but the kernel for it is not installed - # kmodtool would add a dep on that kernel when building; thus when we'd try to install the - # rpms we'd run into a missing-dep problem. Thus we prevent that case - echo "Kernel ${1} not installed" - exit 1 fi + + check_kernel_devel "${1}" + # overwrites the default: if [[ ! -n "${kernels}" ]] ; then kernels="${1}" @@ -600,6 +615,11 @@ done # sanity checks init +# only check for default_kernel if no value have been parsed +if [ -z ${kernels} ] ; then + check_default_kernel +fi + # go for kernel in ${kernels} ; do check_kmods ${kernel} From 2beab063b9eddfd18771fe4a933f5626614d8470 Mon Sep 17 00:00:00 2001 From: Nicolas Chauvet Date: Fri, 23 Aug 2024 14:24:11 +0200 Subject: [PATCH 13/79] Bump to akmods 0.5.10 --- akmods | 2 +- akmods.spec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/akmods b/akmods index d83d033..e716f14 100644 --- a/akmods +++ b/akmods @@ -37,7 +37,7 @@ # global vars myprog="akmods" -myver="0.5.9" +myver="0.5.10" kmodlogfile= continue_line="" tmpdir= diff --git a/akmods.spec b/akmods.spec index cd58bcd..9e33133 100644 --- a/akmods.spec +++ b/akmods.spec @@ -1,5 +1,5 @@ Name: akmods -Version: 0.5.9 +Version: 0.5.10 Release: %autorelease Summary: Automatic kmods build and install tool From 8d2ac12ba19b193ca0b77956a3b30d95518a2884 Mon Sep 17 00:00:00 2001 From: Nicolas Chauvet Date: Fri, 23 Aug 2024 15:27:28 +0200 Subject: [PATCH 14/79] Deprecate akmods-shutdown script One can still use the akmods-shutdown (non-default) service or run akmods directly --- akmods-shutdown | 10 +++++----- akmods-shutdown.service | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/akmods-shutdown b/akmods-shutdown index adcf005..ac97e8f 100644 --- a/akmods-shutdown +++ b/akmods-shutdown @@ -23,9 +23,9 @@ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -echo "Building modules for all installed kernels." -for kernel in /usr/src/kernels/* ; do - kernel=$(basename $kernel) - /usr/sbin/akmods --kernels $kernel -done +echo "This akmods-shutdown script is deprecated and will be removed in the future" +echo "Using akmods instead ..." +sleep 6 + +/usr/sbin/akmods diff --git a/akmods-shutdown.service b/akmods-shutdown.service index 7fcccc1..10e8782 100644 --- a/akmods-shutdown.service +++ b/akmods-shutdown.service @@ -7,7 +7,7 @@ Conflicts=shutdown.target Type=oneshot RemainAfterExit=yes ExecStart=/bin/true -ExecStop=-/usr/sbin/akmods-shutdown +ExecStop=-/usr/sbin/akmods TimeoutStopSec=5min [Install] From 00476863849ff48829543342f1320ab3d767fffe Mon Sep 17 00:00:00 2001 From: Nicolas Chauvet Date: Fri, 23 Aug 2024 15:30:17 +0200 Subject: [PATCH 15/79] akmods --from-init only operates on current kernel --- akmods | 2 ++ 1 file changed, 2 insertions(+) diff --git a/akmods b/akmods index e716f14..941a72d 100644 --- a/akmods +++ b/akmods @@ -577,6 +577,8 @@ while [ "${1}" ] ; do # Clean old logs and rpm files from no more installed kmod # packages. cleanup_cachedir + # akmods --from-init only operates on current kernel + kernels="$(uname -r)" shift ;; --from-posttrans|--from-kernel-posttrans|--from-akmod-posttrans) From 7a4e1dc503884004588dd4950abc65530f0fb907 Mon Sep 17 00:00:00 2001 From: Nicolas Chauvet Date: Fri, 23 Aug 2024 16:15:20 +0200 Subject: [PATCH 16/79] Change check_kernel_devel() to return instead of exit --- akmods | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/akmods b/akmods index 941a72d..5b6f305 100644 --- a/akmods +++ b/akmods @@ -236,15 +236,16 @@ check_kernel_devel() [[ ! -r /lib/modules/"${1}"/build/Makefile ]] ; then echo "Could not find files needed to compile modules for ${1}" echo "Are the development files for kernel ${1} or the appropriate kernel-devel package installed?" - exit 1 + return 1 elif [[ -r /usr/src/kernels/"${1}"/Makefile ]] && \ [[ ! -d /lib/modules/"${1}" ]] ; then # this is a red hat / fedora kernel-devel package, but the kernel for it is not installed # kmodtool would add a dep on that kernel when building; thus when we'd try to install the # rpms we'd run into a missing-dep problem. Thus we prevent that case echo "Kernel ${1} not installed" - exit 1 + return 1 fi + return 0 } check_default_kernel() From b009ad9ae8a006c32a12ee8320728ef562452749 Mon Sep 17 00:00:00 2001 From: Nicolas Chauvet Date: Fri, 23 Aug 2024 16:53:29 +0200 Subject: [PATCH 17/79] Use check_kernel_devel return code as appropriate --- akmods | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/akmods b/akmods index 5b6f305..b8121a6 100644 --- a/akmods +++ b/akmods @@ -268,11 +268,18 @@ check_default_kernel() default_kernel="" fi - check_kernel_devel "${default_kernel}" - - if ! $(echo "${kernels}" | grep -q "${default_kernel}") ; then - kernels="${kernels} ${default_kernel}" + if [[ x${default_kernel} == x"$(uname -r)" ]] ; then + local _kernels="${default_kernel}" + else + local _kernels="${default_kernel} $(uname -r)" fi + + for _kernel in ${_kernels} ; do + if [[ $(check_kernel_devel "${_kernel}" == 0) ]] ; then + kernels="${kernels} ${_kernel}" + fi + done + } buildinstall_kmod() @@ -541,7 +548,10 @@ while [ "${1}" ] ; do exit 1 fi - check_kernel_devel "${1}" + if [[ $(check_kernel_devel "${1}" != 0) ]] ; then + echo "ERROR: kernel or kernel-devel required for ${1}" >&2 + exit 1 + fi # overwrites the default: if [[ ! -n "${kernels}" ]] ; then From 1e800cdb198eb2066e49e4549b5e723fc16c9d78 Mon Sep 17 00:00:00 2001 From: Nicolas Chauvet Date: Fri, 23 Aug 2024 17:01:15 +0200 Subject: [PATCH 18/79] Fix parsing multiple kernel --- akmods | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/akmods b/akmods index b8121a6..d99a7d6 100644 --- a/akmods +++ b/akmods @@ -629,7 +629,7 @@ done init # only check for default_kernel if no value have been parsed -if [ -z ${kernels} ] ; then +if [ -z "${kernels}" ] ; then check_default_kernel fi From 093aa19e60ae724cb993dda7c35371026953a299 Mon Sep 17 00:00:00 2001 From: Rohan Barar Date: Fri, 20 Sep 2024 17:27:18 +1000 Subject: [PATCH 19/79] Removed hard-coded paths. --- akmods-kmodgenca | 123 ++++++++++++++++++++++++++--------------------- 1 file changed, 68 insertions(+), 55 deletions(-) diff --git a/akmods-kmodgenca b/akmods-kmodgenca index eb8d496..7d6cf9c 100644 --- a/akmods-kmodgenca +++ b/akmods-kmodgenca @@ -1,9 +1,11 @@ #!/bin/bash -# -# kmodgenca - Helper script to create CA/Keypair to sign modules. + +# NAME: 'kmodgenca' +# PURPOSE: Helper script to create CA/Keypair to sign modules. # Copyright (c) 2017 Stanislas Leduc # Copyright (c) 2018-2019 Nicolas Viéville -# + +################################################################################ # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including @@ -22,17 +24,32 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -MYPROG="kmodgenca" -MYVER="0.5.7" +################################################################################ + +# DECLARE CONSTANTS +# Strings +readonly SCRIPT_NAME="kmodgenca" +readonly SCRIPT_VERSION="0.5.7" + +# Directories +readonly AKMODS_DIR="/etc/pki/akmods" +readonly PRIVATE_KEY_DIR="${AKMODS_DIR}/private" +readonly PUBLIC_KEY_DIR="${AKMODS_DIR}/certs" + +# Paths +readonly PRIVATE_KEY_PATH="${PRIVATE_KEY_DIR}/private_key.priv" +readonly PUBLIC_KEY_PATH="${PUBLIC_KEY_DIR}/public_key.der" +readonly CACERT_CONFIG_PATH="${AKMODS_DIR}/cacert.config" +readonly RESTORECON_PATH="/usr/sbin/restorecon" + +# DECLARE VARIABLES FORCE_BUILD=0 AUTOMATIC_BUILD=0 AUTOMATIC_BUILD_OPTION="" -myprog_help () -{ +function help () { echo "Build CA/Keypair to sign modules" - echo $'\n'"Usage: ${MYPROG} [OPTIONS]" + echo $'\n'"Usage: ${SCRIPT_NAME} [OPTIONS]" echo $'\n'"Options:" echo " -a, --auto -- generate default values for cacert.config file without prompt" echo " -f, --force -- build CA/Keypair even if there is already ones" @@ -42,7 +59,6 @@ myprog_help () # Parse command line options. -# while [ "${1}" ] ; do case "${1}" in -a|--auto) @@ -54,71 +70,70 @@ while [ "${1}" ] ; do shift ;; -h|--help) - myprog_help + help exit 0 ;; -V|--version) - echo "${MYPROG} ${MYVER}" + echo "${SCRIPT_NAME} ${SCRIPT_VERSION}" exit 0 ;; *) echo "Error: Unknown option '${1}'." >&2 - myprog_help >&2 + help >&2 exit 2 ;; esac done -# Exit early if cert and private key already exist and if FORCE_BUILD -# is not equal to 1. -# -if $(readlink -e /etc/pki/akmods/certs/public_key.der &>/dev/null) && \ - $(readlink -e /etc/pki/akmods/private/private_key.priv &>/dev/null) && \ - [ ${FORCE_BUILD} -eq 0 ] ; then +# Terminate the script when: +# 1. Both a certificate (public key) and private key already exist, AND +# 2. A forced rebuild was not requested (i.e., 'FORCE_BUILD' is NOT set to '1') +if $(readlink -e "$PUBLIC_KEY_PATH" &>/dev/null) && \ + $(readlink -e "$PRIVATE_KEY_PATH" &>/dev/null) && \ + [ "$FORCE_BUILD" -eq 0 ]; then exit 0 fi -CACERT_CONFIG="/etc/pki/akmods/cacert.config" + KEYNAME="$(hostname)"-"$(od -vAn -N4 -tu4 < /dev/urandom | awk '{print $1}')" # Create cacert.config file with local values if AUTOMATIC_BUILD is set # or ask for values manually. -# echo "Update cacert.config..." if [ ${AUTOMATIC_BUILD} -eq 1 ] ; then # Set OpenSSL fields values, comment default values and min/max ones. sed -e "s#\(0.organizationName *= \).*#\1$(hostname)#" \ -e "s#\(organizationalUnitName *= \).*#\1$(hostname)#" \ - -e "s#\(emailAddress *= \).*#\1akmods@$(hostname)#" \ - -e "s#\(localityName *= \).*#\1None#" \ - -e "s#\(stateOrProvinceName *= \).*#\1None#" \ - -e "s#\(countryName *= \).*#\1$(locale country_ab2)#" \ - -e "s#\(commonName *= \).*#\1$(hostname)"-"$(od -vAn -N4 -tu4 < /dev/urandom | awk '{print $1}')#" \ - -e "s/^[^#]*_default *= /#&/" \ - -e "s/^[^#]*_min/#&/" \ - -e "s/^[^#]*_max/#&/" ${CACERT_CONFIG}.in > ${CACERT_CONFIG} + -e "s#\(emailAddress *= \).*#\1akmods@$(hostname)#" \ + -e "s#\(localityName *= \).*#\1None#" \ + -e "s#\(stateOrProvinceName *= \).*#\1None#" \ + -e "s#\(countryName *= \).*#\1$(locale country_ab2)#" \ + -e "s#\(commonName *= \).*#\1$(hostname)"-"$(od -vAn -N4 -tu4 < /dev/urandom | awk '{print $1}')#" \ + -e "s/^[^#]*_default *= /#&/" \ + -e "s/^[^#]*_min/#&/" \ + -e "s/^[^#]*_max/#&/" ${CACERT_CONFIG_PATH}.in > ${CACERT_CONFIG_PATH} AUTOMATIC_BUILD_OPTION=" -batch" else # Activate prompt directive. - sed -e "s#\(prompt *= \).*#\1yes#" ${CACERT_CONFIG}.in > ${CACERT_CONFIG} + sed -e "s#\(prompt *= \).*#\1yes#" ${CACERT_CONFIG_PATH}.in > ${CACERT_CONFIG_PATH} fi + KEY_SUFF="$(date "+%F_%T_%N")" -# If cert and private key files names already exists, do not overwrite -# them but save them. -# -if [[ -e /etc/pki/akmods/certs/${KEYNAME}.der ]] ; then - # If the cert has already been loaded in MOK, add "already_enrolled" - # to the suffix of the backup file. + +# If cert and private key files names already exists, do not overwrite them but save them. +if [[ -e "${PUBLIC_KEY_DIR}/${KEYNAME}.der" ]] ; then + # If the cert has already been loaded in MOK, add "already_enrolled" to the suffix of the backup file. # `mokutil --help` fails if EFI variables are not supported on the # system. It is therefore impossible to test the presence of the key # in MOK, and then do not add special suffix to the backup file. - # - if command -v mokutil && $(mokutil --test-key /etc/pki/akmods/certs/${KEYNAME}.der &> /dev/null) ; then - KEY_SUFF="${KEY_SUFF}_already_enrolled" + if command -v mokutil && $(mokutil --test-key "${PUBLIC_KEY_DIR}/${KEYNAME}.der" &> /dev/null) ; then + KEY_SUFF="${KEY_SUFF}_already_enrolled" fi - mv /etc/pki/akmods/certs/${KEYNAME}.der /etc/pki/akmods/certs/${KEYNAME}.der.${KEY_SUFF}.bak - if [[ -e /etc/pki/akmods/private/${KEYNAME}.priv ]] ; then - mv /etc/pki/akmods/private/${KEYNAME}.priv /etc/pki/akmods/private/${KEYNAME}.priv.${KEY_SUFF}.bak + + mv "${PUBLIC_KEY_DIR}/${KEYNAME}.der" "${PUBLIC_KEY_DIR}/${KEYNAME}.der.${KEY_SUFF}.bak" + + if [[ -e "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" ]] ; then + mv "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" "${PRIVATE_KEY_DIR}/${KEYNAME}.priv.${KEY_SUFF}.bak" fi fi @@ -126,26 +141,24 @@ echo "Generate new keypair..." sg akmods -c " umask 037 openssl req -x509 -new -nodes -utf8 -sha256 -days 3650${AUTOMATIC_BUILD_OPTION} \ - -config ${CACERT_CONFIG} -outform DER \ - -out /etc/pki/akmods/certs/${KEYNAME}.der \ - -keyout /etc/pki/akmods/private/${KEYNAME}.priv + -config ${CACERT_CONFIG_PATH} -outform DER \ + -out "${PUBLIC_KEY_DIR}/${KEYNAME}.der" \ + -keyout "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" " # Ensure that akmods group can read keys. -# -chmod g+r /etc/pki/akmods/certs/${KEYNAME}.* -chmod g+r /etc/pki/akmods/private/${KEYNAME}.* +chmod g+r "${PUBLIC_KEY_DIR}/${KEYNAME}.*" +chmod g+r "${PRIVATE_KEY_DIR}/${KEYNAME}.*" # Sanitize permissions. -# -if [[ -x /usr/sbin/restorecon ]] ; then - /usr/sbin/restorecon /etc/pki/akmods/certs/${KEYNAME}.der - /usr/sbin/restorecon /etc/pki/akmods/private/${KEYNAME}.priv +if [[ -x "$RESTORECON_PATH" ]] ; then + $RESTORECON_PATH "${PUBLIC_KEY_DIR}/${KEYNAME}.der" + $RESTORECON_PATH "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" fi # Update symlink to use new keypair. -# -ln -nsf /etc/pki/akmods/certs/${KEYNAME}.der /etc/pki/akmods/certs/public_key.der -ln -nsf /etc/pki/akmods/private/${KEYNAME}.priv /etc/pki/akmods/private/private_key.priv +ln -nsf "${PUBLIC_KEY_DIR}/${KEYNAME}.der" "${PUBLIC_KEY_DIR}/public_key.der" +ln -nsf "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" "${PRIVATE_KEY_DIR}/private_key.priv" +# Exit script. exit 0 From cf80933cec2e50333bd1f846f38c99d814556b9b Mon Sep 17 00:00:00 2001 From: Rohan Barar Date: Fri, 20 Sep 2024 17:29:09 +1000 Subject: [PATCH 20/79] Utilise robust shebang. --- akmods-kmodgenca | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/akmods-kmodgenca b/akmods-kmodgenca index 7d6cf9c..9c87f9e 100644 --- a/akmods-kmodgenca +++ b/akmods-kmodgenca @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # NAME: 'kmodgenca' # PURPOSE: Helper script to create CA/Keypair to sign modules. From c9c8bbce275566cb9e19e696bc9c2336cfeb84f4 Mon Sep 17 00:00:00 2001 From: Rohan Barar Date: Fri, 20 Sep 2024 17:33:33 +1000 Subject: [PATCH 21/79] Align license to 80 character width. --- akmods-kmodgenca | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/akmods-kmodgenca b/akmods-kmodgenca index 9c87f9e..31eac19 100644 --- a/akmods-kmodgenca +++ b/akmods-kmodgenca @@ -6,24 +6,23 @@ # Copyright (c) 2018-2019 Nicolas Viéville ################################################################################ -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: # -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. # -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. ################################################################################ # DECLARE CONSTANTS From 210129096c8c817331e1e6c16266b68e62ddd022 Mon Sep 17 00:00:00 2001 From: Rohan Barar Date: Fri, 20 Sep 2024 18:04:26 +1000 Subject: [PATCH 22/79] Various changes to avoid ShellCheck warnings. --- akmods-kmodgenca | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/akmods-kmodgenca b/akmods-kmodgenca index 31eac19..1732d5d 100644 --- a/akmods-kmodgenca +++ b/akmods-kmodgenca @@ -87,13 +87,12 @@ done # Terminate the script when: # 1. Both a certificate (public key) and private key already exist, AND # 2. A forced rebuild was not requested (i.e., 'FORCE_BUILD' is NOT set to '1') -if $(readlink -e "$PUBLIC_KEY_PATH" &>/dev/null) && \ - $(readlink -e "$PRIVATE_KEY_PATH" &>/dev/null) && \ +if readlink -e "$PUBLIC_KEY_PATH" &>/dev/null && \ + readlink -e "$PRIVATE_KEY_PATH" &>/dev/null && \ [ "$FORCE_BUILD" -eq 0 ]; then - exit 0 + exit 0 fi - KEYNAME="$(hostname)"-"$(od -vAn -N4 -tu4 < /dev/urandom | awk '{print $1}')" # Create cacert.config file with local values if AUTOMATIC_BUILD is set @@ -107,11 +106,11 @@ if [ ${AUTOMATIC_BUILD} -eq 1 ] ; then -e "s#\(localityName *= \).*#\1None#" \ -e "s#\(stateOrProvinceName *= \).*#\1None#" \ -e "s#\(countryName *= \).*#\1$(locale country_ab2)#" \ - -e "s#\(commonName *= \).*#\1$(hostname)"-"$(od -vAn -N4 -tu4 < /dev/urandom | awk '{print $1}')#" \ + -e "s#\(commonName *= \).*#\1$(hostname)-$(od -vAn -N4 -tu4 < /dev/urandom | awk '{print $1}')#" \ -e "s/^[^#]*_default *= /#&/" \ -e "s/^[^#]*_min/#&/" \ -e "s/^[^#]*_max/#&/" ${CACERT_CONFIG_PATH}.in > ${CACERT_CONFIG_PATH} - AUTOMATIC_BUILD_OPTION=" -batch" + AUTOMATIC_BUILD_OPTION="-batch" else # Activate prompt directive. sed -e "s#\(prompt *= \).*#\1yes#" ${CACERT_CONFIG_PATH}.in > ${CACERT_CONFIG_PATH} @@ -125,7 +124,7 @@ if [[ -e "${PUBLIC_KEY_DIR}/${KEYNAME}.der" ]] ; then # `mokutil --help` fails if EFI variables are not supported on the # system. It is therefore impossible to test the presence of the key # in MOK, and then do not add special suffix to the backup file. - if command -v mokutil && $(mokutil --test-key "${PUBLIC_KEY_DIR}/${KEYNAME}.der" &> /dev/null) ; then + if command -v mokutil && mokutil --test-key "${PUBLIC_KEY_DIR}/${KEYNAME}.der" &> /dev/null; then KEY_SUFF="${KEY_SUFF}_already_enrolled" fi @@ -136,14 +135,26 @@ if [[ -e "${PUBLIC_KEY_DIR}/${KEYNAME}.der" ]] ; then fi fi -echo "Generate new keypair..." -sg akmods -c " -umask 037 -openssl req -x509 -new -nodes -utf8 -sha256 -days 3650${AUTOMATIC_BUILD_OPTION} \ - -config ${CACERT_CONFIG_PATH} -outform DER \ - -out "${PUBLIC_KEY_DIR}/${KEYNAME}.der" \ - -keyout "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" -" +echo "Generate new key pair..." + +# Prepare an OpenSSL command to generate the key pair. +keypair_generation_command=( + "openssl req" # Request new certificate + "-x509" # X.509 certificate type + "-new" # New key pair + "-nodes" # No DES + "-utf8" # UTF-8 encoding + "-sha256" # SHA-256 hash algorithm + "-days" "3650" # 10 year cert validity + "${AUTOMATIC_BUILD_OPTION}" # Empty or "-batch" + "-config" "${CACERT_CONFIG_PATH}" # Configuration file path + "-outform" "DER" # DER output format + "-out" "${PUBLIC_KEY_DIR}/${KEYNAME}.der" # Public key output path + "-keyout" "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" # Private key output path +) + +# Execute the key pair generation command within the 'akmods' group context. +sg akmods -c "umask 037 && ${keypair_generation_command[*]}" # Ensure that akmods group can read keys. chmod g+r "${PUBLIC_KEY_DIR}/${KEYNAME}.*" From 8ae38a49ce44e82dd1fccdb1b1219b9a0f502718 Mon Sep 17 00:00:00 2001 From: Rohan Barar Date: Fri, 20 Sep 2024 18:05:08 +1000 Subject: [PATCH 23/79] Updated copyright information. --- akmods-kmodgenca | 1 + 1 file changed, 1 insertion(+) diff --git a/akmods-kmodgenca b/akmods-kmodgenca index 1732d5d..477220b 100644 --- a/akmods-kmodgenca +++ b/akmods-kmodgenca @@ -4,6 +4,7 @@ # PURPOSE: Helper script to create CA/Keypair to sign modules. # Copyright (c) 2017 Stanislas Leduc # Copyright (c) 2018-2019 Nicolas Viéville +# Copyright (c) 2024 Rohan Barar ################################################################################ # Permission is hereby granted, free of charge, to any person obtaining a copy From 73f5cbedb8d9b5dd24a7cf70e049517455a13304 Mon Sep 17 00:00:00 2001 From: Rohan Barar Date: Fri, 20 Sep 2024 18:20:03 +1000 Subject: [PATCH 24/79] Improved user feedback in event of existing key pair. --- akmods-kmodgenca | 47 +++++++++++++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/akmods-kmodgenca b/akmods-kmodgenca index 477220b..4351a60 100644 --- a/akmods-kmodgenca +++ b/akmods-kmodgenca @@ -42,25 +42,29 @@ readonly PUBLIC_KEY_PATH="${PUBLIC_KEY_DIR}/public_key.der" readonly CACERT_CONFIG_PATH="${AKMODS_DIR}/cacert.config" readonly RESTORECON_PATH="/usr/sbin/restorecon" +# ANSI +readonly BOLD_RED_TEXT="\e[1;31m" +readonly BOLD_YELLOW_TEXT="\e[1;33m" +readonly CLEAR_TEXT="\e[0m" + # DECLARE VARIABLES FORCE_BUILD=0 AUTOMATIC_BUILD=0 AUTOMATIC_BUILD_OPTION="" -function help () { - echo "Build CA/Keypair to sign modules" - echo $'\n'"Usage: ${SCRIPT_NAME} [OPTIONS]" - echo $'\n'"Options:" - echo " -a, --auto -- generate default values for cacert.config file without prompt" - echo " -f, --force -- build CA/Keypair even if there is already ones" - echo " -h, --help -- print usage" - echo " -V, --version -- show version" +function help() { + echo "Creates a Certificate Authority (CA) and key pair for module signing." + echo -e "\nUsage: ${SCRIPT_NAME} [OPTIONS]" + echo -e "\nOptions:" + echo " -a, --auto Utilise default values for 'cacert.config'." + echo " -f, --force Create CA/Keypair even if one already exists." + echo " -h, --help Display this help message." + echo " -V, --version Display script version information." } - -# Parse command line options. -while [ "${1}" ] ; do - case "${1}" in +# Parse any supplied arguments. +while [ "$1" ] ; do + case "$1" in -a|--auto) AUTOMATIC_BUILD=1 shift @@ -74,13 +78,13 @@ while [ "${1}" ] ; do exit 0 ;; -V|--version) - echo "${SCRIPT_NAME} ${SCRIPT_VERSION}" + echo "${SCRIPT_NAME} v${SCRIPT_VERSION}" exit 0 ;; *) - echo "Error: Unknown option '${1}'." >&2 + echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} Unknown option '${1}'." >&2 help >&2 - exit 2 + exit 1 ;; esac done @@ -89,9 +93,16 @@ done # 1. Both a certificate (public key) and private key already exist, AND # 2. A forced rebuild was not requested (i.e., 'FORCE_BUILD' is NOT set to '1') if readlink -e "$PUBLIC_KEY_PATH" &>/dev/null && \ - readlink -e "$PRIVATE_KEY_PATH" &>/dev/null && \ - [ "$FORCE_BUILD" -eq 0 ]; then - exit 0 + readlink -e "$PRIVATE_KEY_PATH" &>/dev/null && \ + [ "$FORCE_BUILD" -eq 0 ]; then + + # Notify user. + echo -e "${BOLD_YELLOW_TEXT}WARNING:${CLEAR_TEXT} EXISTING KEY PAIR." + echo "Please specify argument '--force' to overwrite the existing key pair." + echo "Quitting." + + # Exit script. + exit 0 fi KEYNAME="$(hostname)"-"$(od -vAn -N4 -tu4 < /dev/urandom | awk '{print $1}')" From 439976bc01a6b69069cd66ef2168097bd640dead Mon Sep 17 00:00:00 2001 From: Rohan Barar Date: Fri, 20 Sep 2024 18:49:58 +1000 Subject: [PATCH 25/79] Added logic to detect broken existing key pairs. --- akmods-kmodgenca | 131 +++++++++++++++++++++++++++++++---------------- 1 file changed, 88 insertions(+), 43 deletions(-) diff --git a/akmods-kmodgenca b/akmods-kmodgenca index 4351a60..fbdaf78 100644 --- a/akmods-kmodgenca +++ b/akmods-kmodgenca @@ -26,11 +26,20 @@ # SOFTWARE. ################################################################################ +# EXIT STATUSES +# 0 - SUCCESS +# 1 - INVALID ARGUMENT +# 2 - BROKEN EXISTING KEY PAIR + # DECLARE CONSTANTS -# Strings +# Script Information readonly SCRIPT_NAME="kmodgenca" readonly SCRIPT_VERSION="0.5.7" +# New Key Pair Name (Hostname + 32-Bit Unsigned Integer) +KEYNAME="$(hostname)"-"$(od -vAn -N4 -tu4 < /dev/urandom | awk '{print $1}')" +readonly KEYNAME + # Directories readonly AKMODS_DIR="/etc/pki/akmods" readonly PRIVATE_KEY_DIR="${AKMODS_DIR}/private" @@ -45,6 +54,7 @@ readonly RESTORECON_PATH="/usr/sbin/restorecon" # ANSI readonly BOLD_RED_TEXT="\e[1;31m" readonly BOLD_YELLOW_TEXT="\e[1;33m" +readonly BOLD_GREEN_TEXT="\033[1;32m" readonly CLEAR_TEXT="\e[0m" # DECLARE VARIABLES @@ -52,6 +62,7 @@ FORCE_BUILD=0 AUTOMATIC_BUILD=0 AUTOMATIC_BUILD_OPTION="" +# FUNCTIONS function help() { echo "Creates a Certificate Authority (CA) and key pair for module signing." echo -e "\nUsage: ${SCRIPT_NAME} [OPTIONS]" @@ -62,50 +73,84 @@ function help() { echo " -V, --version Display script version information." } +function parse_arguments() { + while [ "$1" ] ; do + case "$1" in + -a|--auto) + AUTOMATIC_BUILD=1 + shift + ;; + -f|--force) + FORCE_BUILD=1 + shift + ;; + -h|--help) + help + exit 0 + ;; + -V|--version) + echo "${SCRIPT_NAME} v${SCRIPT_VERSION}" + exit 0 + ;; + *) + echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} INVALID OPTION '${1}'." >&2 + help >&2 + exit 1 + ;; + esac + done +} + +function check_broken_key_pair() { + # Terminate the script when: + # 1. A certificate (public key) OR private key exists (but not both), AND + # 2. A forced rebuild was not requested (i.e., 'FORCE_BUILD' is NOT '1') + local pub_key_exists=$(readlink -e "$PUBLIC_KEY_PATH" &>/dev/null && echo 1 || echo 0) + local pri_key_exists=$(readlink -e "$PRIVATE_KEY_PATH" &>/dev/null && echo 1 || echo 0) + + if [[ "$pub_key_exists" -ne "$pri_key_exists" && "$FORCE_BUILD" -eq 0 ]]; then + # Notify user. + echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} BROKEN EXISTING KEY PAIR." + echo "Both a public key and a private key must exist." + echo "Currently, only a single key is present." + + # Dynamic status output with colours. + echo -e " ${PUBLIC_KEY_PATH}: $( [[ $pub_key_exists -eq 1 ]] && echo -e "${BOLD_GREEN_TEXT}PRESENT${CLEAR_TEXT}" || echo -e "${BOLD_RED_TEXT}MISSING${CLEAR_TEXT}" )" + echo -e " ${PRIVATE_KEY_PATH}: $( [[ $pri_key_exists -eq 1 ]] && echo -e "${BOLD_GREEN_TEXT}PRESENT${CLEAR_TEXT}" || echo -e "${BOLD_RED_TEXT}MISSING${CLEAR_TEXT}" )" + echo "Quitting." + + # Exit script. + exit 2 + fi +} + +function check_existing_key_pair() { + # Terminate the script when: + # 1. Both a certificate (public key) and private key already exist, AND + # 2. A forced rebuild was not requested (i.e., 'FORCE_BUILD' is NOT '1') + if readlink -e "$PUBLIC_KEY_PATH" &>/dev/null && \ + readlink -e "$PRIVATE_KEY_PATH" &>/dev/null && \ + [ "$FORCE_BUILD" -eq 0 ]; then + + # Notify user. + echo -e "${BOLD_YELLOW_TEXT}WARNING:${CLEAR_TEXT} EXISTING KEY PAIR." + echo "Please specify argument '--force' to overwrite the existing key pair." + echo "Quitting." + + # Exit script. + exit 0 + fi +} + +# SCRIPT MAINLINE # Parse any supplied arguments. -while [ "$1" ] ; do - case "$1" in - -a|--auto) - AUTOMATIC_BUILD=1 - shift - ;; - -f|--force) - FORCE_BUILD=1 - shift - ;; - -h|--help) - help - exit 0 - ;; - -V|--version) - echo "${SCRIPT_NAME} v${SCRIPT_VERSION}" - exit 0 - ;; - *) - echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} Unknown option '${1}'." >&2 - help >&2 - exit 1 - ;; - esac -done +parse_arguments "$@" -# Terminate the script when: -# 1. Both a certificate (public key) and private key already exist, AND -# 2. A forced rebuild was not requested (i.e., 'FORCE_BUILD' is NOT set to '1') -if readlink -e "$PUBLIC_KEY_PATH" &>/dev/null && \ - readlink -e "$PRIVATE_KEY_PATH" &>/dev/null && \ - [ "$FORCE_BUILD" -eq 0 ]; then +# Check for broken key pairs. +check_broken_key_pair - # Notify user. - echo -e "${BOLD_YELLOW_TEXT}WARNING:${CLEAR_TEXT} EXISTING KEY PAIR." - echo "Please specify argument '--force' to overwrite the existing key pair." - echo "Quitting." - - # Exit script. - exit 0 -fi - -KEYNAME="$(hostname)"-"$(od -vAn -N4 -tu4 < /dev/urandom | awk '{print $1}')" +# Check for existing key pair. +check_existing_key_pair # Create cacert.config file with local values if AUTOMATIC_BUILD is set # or ask for values manually. @@ -136,7 +181,7 @@ if [[ -e "${PUBLIC_KEY_DIR}/${KEYNAME}.der" ]] ; then # `mokutil --help` fails if EFI variables are not supported on the # system. It is therefore impossible to test the presence of the key # in MOK, and then do not add special suffix to the backup file. - if command -v mokutil && mokutil --test-key "${PUBLIC_KEY_DIR}/${KEYNAME}.der" &> /dev/null; then + if command -v mokutil && mokutil --test-key "${PUBLIC_KEY_DIR}/${KEYNAME}.der" &>/dev/null; then KEY_SUFF="${KEY_SUFF}_already_enrolled" fi From 5186db3662388ef70ca65062ea28a8c1275a9a64 Mon Sep 17 00:00:00 2001 From: Rohan Barar Date: Fri, 20 Sep 2024 19:31:06 +1000 Subject: [PATCH 26/79] Extract functions to enhance readability + Set 'commonName' to match 'KEYNAME'. --- akmods-kmodgenca | 170 ++++++++++++++++++++++++++++------------------- 1 file changed, 100 insertions(+), 70 deletions(-) diff --git a/akmods-kmodgenca b/akmods-kmodgenca index fbdaf78..e10fbad 100644 --- a/akmods-kmodgenca +++ b/akmods-kmodgenca @@ -37,7 +37,7 @@ readonly SCRIPT_NAME="kmodgenca" readonly SCRIPT_VERSION="0.5.7" # New Key Pair Name (Hostname + 32-Bit Unsigned Integer) -KEYNAME="$(hostname)"-"$(od -vAn -N4 -tu4 < /dev/urandom | awk '{print $1}')" +KEYNAME="$(hostname)-$(od -vAn -N4 -tu4 < /dev/urandom | awk '{print $1}')" readonly KEYNAME # Directories @@ -61,6 +61,7 @@ readonly CLEAR_TEXT="\e[0m" FORCE_BUILD=0 AUTOMATIC_BUILD=0 AUTOMATIC_BUILD_OPTION="" +KEY_SUFFIX="$(date "+%F_%T_%N")" # FUNCTIONS function help() { @@ -105,7 +106,11 @@ function check_broken_key_pair() { # Terminate the script when: # 1. A certificate (public key) OR private key exists (but not both), AND # 2. A forced rebuild was not requested (i.e., 'FORCE_BUILD' is NOT '1') + + # shellcheck disable=SC2155 local pub_key_exists=$(readlink -e "$PUBLIC_KEY_PATH" &>/dev/null && echo 1 || echo 0) + + # shellcheck disable=SC2155 local pri_key_exists=$(readlink -e "$PRIVATE_KEY_PATH" &>/dev/null && echo 1 || echo 0) if [[ "$pub_key_exists" -ne "$pri_key_exists" && "$FORCE_BUILD" -eq 0 ]]; then @@ -142,6 +147,91 @@ function check_existing_key_pair() { fi } +function create_ca_cert_config() { + echo "UPDATING '${CACERT_CONFIG_PATH}'..." + if [ "$AUTOMATIC_BUILD" -eq 1 ]; then + # Utilise default values if 'AUTOMATIC_BUILD' is equal to '1'. + # Set OpenSSL field values. + # Comment default and min/max values. + sed -e "s#\(0.organizationName *= \).*#\1$(hostname)#" \ + -e "s#\(organizationalUnitName *= \).*#\1$(hostname)#" \ + -e "s#\(emailAddress *= \).*#\1akmods@$(hostname)#" \ + -e "s#\(localityName *= \).*#\1None#" \ + -e "s#\(stateOrProvinceName *= \).*#\1None#" \ + -e "s#\(countryName *= \).*#\1$(locale country_ab2)#" \ + -e "s#\(commonName *= \).*#\1${KEYNAME}#" \ + -e "s/^[^#]*_default *= /#&/" \ + -e "s/^[^#]*_min/#&/" \ + -e "s/^[^#]*_max/#&/" "${CACERT_CONFIG_PATH}.in" > "$CACERT_CONFIG_PATH" + AUTOMATIC_BUILD_OPTION="-batch" + else + # Request user enter values manually if 'AUTOMATIC_BUILD' is equal to '0'. + # Request OpenSSL prompt user for values later. + sed -e "s#\(prompt *= \).*#\1yes#" "${CACERT_CONFIG_PATH}.in" > "$CACERT_CONFIG_PATH" + fi +} + +function backup_existing_key_pair() { + # Check if the randomly-generated key pair name conflicts with an existing pair. + if [[ -e "${PUBLIC_KEY_DIR}/${KEYNAME}.der" ]] ; then + # If the public key (certificate) has already been enrolled in the UEFI, append "_enrolled" to the suffix of the backup file. + # Note: `mokutil --help` fails if EFI variables are not supported on the system. + # If it is impossible to ascertain if the MOK is enrolled in the UEFI, do not add the "_enrolled" suffix to the backup file. + if command -v mokutil && mokutil --test-key "${PUBLIC_KEY_DIR}/${KEYNAME}.der" &>/dev/null; then + KEY_SUFFIX="${KEY_SUFFIX}_enrolled" + fi + + # Rename the existing public key with the conflicting name. + mv "${PUBLIC_KEY_DIR}/${KEYNAME}.der" "${PUBLIC_KEY_DIR}/${KEYNAME}.der.${KEY_SUFFIX}.bak" + + # Rename the existing private key with the conflicting name. + if [[ -e "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" ]] ; then + mv "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" "${PRIVATE_KEY_DIR}/${KEYNAME}.priv.${KEY_SUFFIX}.bak" + fi + fi +} + +function create_new_keypair() { + echo "CREATING NEW KEY PAIR..." + + # Prepare an OpenSSL command to generate the key pair. + local keypair_generation_command=( + "openssl req" # Request new certificate + "-x509" # X.509 certificate type + "-new" # New key pair + "-nodes" # No DES + "-utf8" # UTF-8 encoding + "-sha256" # SHA-256 hash algorithm + "-days" "3650" # 10 year cert validity + "${AUTOMATIC_BUILD_OPTION}" # Empty or "-batch" + "-config" "${CACERT_CONFIG_PATH}" # Configuration file path + "-outform" "DER" # DER output format + "-out" "${PUBLIC_KEY_DIR}/${KEYNAME}.der" # Public key output path + "-keyout" "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" # Private key output path + ) + + # Execute the key pair generation command within the 'akmods' group context. + # Ensure 'rw-rwx---' permissions. + sg akmods -c "umask 037 && ${keypair_generation_command[*]}" +} + +function set_key_permissions() { + # Ensure that akmods group can read keys. + chmod g+r "${PUBLIC_KEY_DIR}/${KEYNAME}.*" + chmod g+r "${PRIVATE_KEY_DIR}/${KEYNAME}.*" + + # Sanitise permissions. + if [[ -x "$RESTORECON_PATH" ]] ; then + $RESTORECON_PATH "${PUBLIC_KEY_DIR}/${KEYNAME}.der" + $RESTORECON_PATH "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" + fi +} + +function update_key_symlinks() { + ln -nsf "${PUBLIC_KEY_DIR}/${KEYNAME}.der" "$PUBLIC_KEY_PATH" + ln -nsf "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" "$PRIVATE_KEY_PATH" +} + # SCRIPT MAINLINE # Parse any supplied arguments. parse_arguments "$@" @@ -152,80 +242,20 @@ check_broken_key_pair # Check for existing key pair. check_existing_key_pair -# Create cacert.config file with local values if AUTOMATIC_BUILD is set -# or ask for values manually. -echo "Update cacert.config..." -if [ ${AUTOMATIC_BUILD} -eq 1 ] ; then - # Set OpenSSL fields values, comment default values and min/max ones. - sed -e "s#\(0.organizationName *= \).*#\1$(hostname)#" \ - -e "s#\(organizationalUnitName *= \).*#\1$(hostname)#" \ - -e "s#\(emailAddress *= \).*#\1akmods@$(hostname)#" \ - -e "s#\(localityName *= \).*#\1None#" \ - -e "s#\(stateOrProvinceName *= \).*#\1None#" \ - -e "s#\(countryName *= \).*#\1$(locale country_ab2)#" \ - -e "s#\(commonName *= \).*#\1$(hostname)-$(od -vAn -N4 -tu4 < /dev/urandom | awk '{print $1}')#" \ - -e "s/^[^#]*_default *= /#&/" \ - -e "s/^[^#]*_min/#&/" \ - -e "s/^[^#]*_max/#&/" ${CACERT_CONFIG_PATH}.in > ${CACERT_CONFIG_PATH} - AUTOMATIC_BUILD_OPTION="-batch" -else - # Activate prompt directive. - sed -e "s#\(prompt *= \).*#\1yes#" ${CACERT_CONFIG_PATH}.in > ${CACERT_CONFIG_PATH} -fi +# Create 'cacert.config' using template file 'cacert.config.in'. +create_ca_cert_config -KEY_SUFF="$(date "+%F_%T_%N")" +# Avoid overwriting key pairs with the same randomly-generated name. +backup_existing_key_pair -# If cert and private key files names already exists, do not overwrite them but save them. -if [[ -e "${PUBLIC_KEY_DIR}/${KEYNAME}.der" ]] ; then - # If the cert has already been loaded in MOK, add "already_enrolled" to the suffix of the backup file. - # `mokutil --help` fails if EFI variables are not supported on the - # system. It is therefore impossible to test the presence of the key - # in MOK, and then do not add special suffix to the backup file. - if command -v mokutil && mokutil --test-key "${PUBLIC_KEY_DIR}/${KEYNAME}.der" &>/dev/null; then - KEY_SUFF="${KEY_SUFF}_already_enrolled" - fi - - mv "${PUBLIC_KEY_DIR}/${KEYNAME}.der" "${PUBLIC_KEY_DIR}/${KEYNAME}.der.${KEY_SUFF}.bak" - - if [[ -e "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" ]] ; then - mv "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" "${PRIVATE_KEY_DIR}/${KEYNAME}.priv.${KEY_SUFF}.bak" - fi -fi +# Create new keypair. +create_new_keypair -echo "Generate new key pair..." - -# Prepare an OpenSSL command to generate the key pair. -keypair_generation_command=( - "openssl req" # Request new certificate - "-x509" # X.509 certificate type - "-new" # New key pair - "-nodes" # No DES - "-utf8" # UTF-8 encoding - "-sha256" # SHA-256 hash algorithm - "-days" "3650" # 10 year cert validity - "${AUTOMATIC_BUILD_OPTION}" # Empty or "-batch" - "-config" "${CACERT_CONFIG_PATH}" # Configuration file path - "-outform" "DER" # DER output format - "-out" "${PUBLIC_KEY_DIR}/${KEYNAME}.der" # Public key output path - "-keyout" "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" # Private key output path -) - -# Execute the key pair generation command within the 'akmods' group context. -sg akmods -c "umask 037 && ${keypair_generation_command[*]}" - -# Ensure that akmods group can read keys. -chmod g+r "${PUBLIC_KEY_DIR}/${KEYNAME}.*" -chmod g+r "${PRIVATE_KEY_DIR}/${KEYNAME}.*" - -# Sanitize permissions. -if [[ -x "$RESTORECON_PATH" ]] ; then - $RESTORECON_PATH "${PUBLIC_KEY_DIR}/${KEYNAME}.der" - $RESTORECON_PATH "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" -fi +# Set permissions and sanitise keys. +set_key_permissions # Update symlink to use new keypair. -ln -nsf "${PUBLIC_KEY_DIR}/${KEYNAME}.der" "${PUBLIC_KEY_DIR}/public_key.der" -ln -nsf "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" "${PRIVATE_KEY_DIR}/private_key.priv" +update_key_symlinks # Exit script. exit 0 From 9da671e61d6fcab7dd8e16782c70e73246f90d6a Mon Sep 17 00:00:00 2001 From: Rohan Barar Date: Fri, 20 Sep 2024 19:36:23 +1000 Subject: [PATCH 27/79] Whitespace changes for consistency. --- akmods-kmodgenca | 242 +++++++++++++++++++++++------------------------ 1 file changed, 121 insertions(+), 121 deletions(-) diff --git a/akmods-kmodgenca b/akmods-kmodgenca index e10fbad..e47bd4b 100644 --- a/akmods-kmodgenca +++ b/akmods-kmodgenca @@ -75,161 +75,161 @@ function help() { } function parse_arguments() { - while [ "$1" ] ; do - case "$1" in - -a|--auto) - AUTOMATIC_BUILD=1 - shift - ;; - -f|--force) - FORCE_BUILD=1 - shift - ;; - -h|--help) - help - exit 0 - ;; - -V|--version) - echo "${SCRIPT_NAME} v${SCRIPT_VERSION}" - exit 0 - ;; - *) - echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} INVALID OPTION '${1}'." >&2 - help >&2 - exit 1 - ;; - esac - done + while [ "$1" ] ; do + case "$1" in + -a|--auto) + AUTOMATIC_BUILD=1 + shift + ;; + -f|--force) + FORCE_BUILD=1 + shift + ;; + -h|--help) + help + exit 0 + ;; + -V|--version) + echo "${SCRIPT_NAME} v${SCRIPT_VERSION}" + exit 0 + ;; + *) + echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} INVALID OPTION '${1}'." >&2 + help >&2 + exit 1 + ;; + esac + done } function check_broken_key_pair() { - # Terminate the script when: - # 1. A certificate (public key) OR private key exists (but not both), AND - # 2. A forced rebuild was not requested (i.e., 'FORCE_BUILD' is NOT '1') + # Terminate the script when: + # 1. A certificate (public key) OR private key exists (but not both), AND + # 2. A forced rebuild was not requested (i.e., 'FORCE_BUILD' is NOT '1') - # shellcheck disable=SC2155 - local pub_key_exists=$(readlink -e "$PUBLIC_KEY_PATH" &>/dev/null && echo 1 || echo 0) + # shellcheck disable=SC2155 + local pub_key_exists=$(readlink -e "$PUBLIC_KEY_PATH" &>/dev/null && echo 1 || echo 0) - # shellcheck disable=SC2155 - local pri_key_exists=$(readlink -e "$PRIVATE_KEY_PATH" &>/dev/null && echo 1 || echo 0) + # shellcheck disable=SC2155 + local pri_key_exists=$(readlink -e "$PRIVATE_KEY_PATH" &>/dev/null && echo 1 || echo 0) - if [[ "$pub_key_exists" -ne "$pri_key_exists" && "$FORCE_BUILD" -eq 0 ]]; then - # Notify user. - echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} BROKEN EXISTING KEY PAIR." - echo "Both a public key and a private key must exist." - echo "Currently, only a single key is present." + if [[ "$pub_key_exists" -ne "$pri_key_exists" && "$FORCE_BUILD" -eq 0 ]]; then + # Notify user. + echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} BROKEN EXISTING KEY PAIR." + echo "Both a public key and a private key must exist." + echo "Currently, only a single key is present." - # Dynamic status output with colours. - echo -e " ${PUBLIC_KEY_PATH}: $( [[ $pub_key_exists -eq 1 ]] && echo -e "${BOLD_GREEN_TEXT}PRESENT${CLEAR_TEXT}" || echo -e "${BOLD_RED_TEXT}MISSING${CLEAR_TEXT}" )" - echo -e " ${PRIVATE_KEY_PATH}: $( [[ $pri_key_exists -eq 1 ]] && echo -e "${BOLD_GREEN_TEXT}PRESENT${CLEAR_TEXT}" || echo -e "${BOLD_RED_TEXT}MISSING${CLEAR_TEXT}" )" - echo "Quitting." + # Dynamic status output with colours. + echo -e " ${PUBLIC_KEY_PATH}: $( [[ $pub_key_exists -eq 1 ]] && echo -e "${BOLD_GREEN_TEXT}PRESENT${CLEAR_TEXT}" || echo -e "${BOLD_RED_TEXT}MISSING${CLEAR_TEXT}" )" + echo -e " ${PRIVATE_KEY_PATH}: $( [[ $pri_key_exists -eq 1 ]] && echo -e "${BOLD_GREEN_TEXT}PRESENT${CLEAR_TEXT}" || echo -e "${BOLD_RED_TEXT}MISSING${CLEAR_TEXT}" )" + echo "Quitting." - # Exit script. - exit 2 - fi + # Exit script. + exit 2 + fi } function check_existing_key_pair() { - # Terminate the script when: - # 1. Both a certificate (public key) and private key already exist, AND - # 2. A forced rebuild was not requested (i.e., 'FORCE_BUILD' is NOT '1') - if readlink -e "$PUBLIC_KEY_PATH" &>/dev/null && \ - readlink -e "$PRIVATE_KEY_PATH" &>/dev/null && \ - [ "$FORCE_BUILD" -eq 0 ]; then + # Terminate the script when: + # 1. Both a certificate (public key) and private key already exist, AND + # 2. A forced rebuild was not requested (i.e., 'FORCE_BUILD' is NOT '1') + if readlink -e "$PUBLIC_KEY_PATH" &>/dev/null && \ + readlink -e "$PRIVATE_KEY_PATH" &>/dev/null && \ + [ "$FORCE_BUILD" -eq 0 ]; then - # Notify user. - echo -e "${BOLD_YELLOW_TEXT}WARNING:${CLEAR_TEXT} EXISTING KEY PAIR." - echo "Please specify argument '--force' to overwrite the existing key pair." - echo "Quitting." + # Notify user. + echo -e "${BOLD_YELLOW_TEXT}WARNING:${CLEAR_TEXT} EXISTING KEY PAIR." + echo "Please specify argument '--force' to overwrite the existing key pair." + echo "Quitting." - # Exit script. - exit 0 - fi + # Exit script. + exit 0 + fi } function create_ca_cert_config() { - echo "UPDATING '${CACERT_CONFIG_PATH}'..." - if [ "$AUTOMATIC_BUILD" -eq 1 ]; then - # Utilise default values if 'AUTOMATIC_BUILD' is equal to '1'. - # Set OpenSSL field values. - # Comment default and min/max values. - sed -e "s#\(0.organizationName *= \).*#\1$(hostname)#" \ - -e "s#\(organizationalUnitName *= \).*#\1$(hostname)#" \ - -e "s#\(emailAddress *= \).*#\1akmods@$(hostname)#" \ - -e "s#\(localityName *= \).*#\1None#" \ - -e "s#\(stateOrProvinceName *= \).*#\1None#" \ - -e "s#\(countryName *= \).*#\1$(locale country_ab2)#" \ - -e "s#\(commonName *= \).*#\1${KEYNAME}#" \ - -e "s/^[^#]*_default *= /#&/" \ - -e "s/^[^#]*_min/#&/" \ - -e "s/^[^#]*_max/#&/" "${CACERT_CONFIG_PATH}.in" > "$CACERT_CONFIG_PATH" - AUTOMATIC_BUILD_OPTION="-batch" - else - # Request user enter values manually if 'AUTOMATIC_BUILD' is equal to '0'. - # Request OpenSSL prompt user for values later. - sed -e "s#\(prompt *= \).*#\1yes#" "${CACERT_CONFIG_PATH}.in" > "$CACERT_CONFIG_PATH" - fi + echo "UPDATING '${CACERT_CONFIG_PATH}'..." + if [ "$AUTOMATIC_BUILD" -eq 1 ]; then + # Utilise default values if 'AUTOMATIC_BUILD' is equal to '1'. + # Set OpenSSL field values. + # Comment default and min/max values. + sed -e "s#\(0.organizationName *= \).*#\1$(hostname)#" \ + -e "s#\(organizationalUnitName *= \).*#\1$(hostname)#" \ + -e "s#\(emailAddress *= \).*#\1akmods@$(hostname)#" \ + -e "s#\(localityName *= \).*#\1None#" \ + -e "s#\(stateOrProvinceName *= \).*#\1None#" \ + -e "s#\(countryName *= \).*#\1$(locale country_ab2)#" \ + -e "s#\(commonName *= \).*#\1${KEYNAME}#" \ + -e "s/^[^#]*_default *= /#&/" \ + -e "s/^[^#]*_min/#&/" \ + -e "s/^[^#]*_max/#&/" "${CACERT_CONFIG_PATH}.in" > "$CACERT_CONFIG_PATH" + AUTOMATIC_BUILD_OPTION="-batch" + else + # Request user enter values manually if 'AUTOMATIC_BUILD' is equal to '0'. + # Request OpenSSL prompt user for values later. + sed -e "s#\(prompt *= \).*#\1yes#" "${CACERT_CONFIG_PATH}.in" > "$CACERT_CONFIG_PATH" + fi } function backup_existing_key_pair() { - # Check if the randomly-generated key pair name conflicts with an existing pair. - if [[ -e "${PUBLIC_KEY_DIR}/${KEYNAME}.der" ]] ; then - # If the public key (certificate) has already been enrolled in the UEFI, append "_enrolled" to the suffix of the backup file. - # Note: `mokutil --help` fails if EFI variables are not supported on the system. - # If it is impossible to ascertain if the MOK is enrolled in the UEFI, do not add the "_enrolled" suffix to the backup file. - if command -v mokutil && mokutil --test-key "${PUBLIC_KEY_DIR}/${KEYNAME}.der" &>/dev/null; then - KEY_SUFFIX="${KEY_SUFFIX}_enrolled" - fi - - # Rename the existing public key with the conflicting name. - mv "${PUBLIC_KEY_DIR}/${KEYNAME}.der" "${PUBLIC_KEY_DIR}/${KEYNAME}.der.${KEY_SUFFIX}.bak" + # Check if the randomly-generated key pair name conflicts with an existing pair. + if [[ -e "${PUBLIC_KEY_DIR}/${KEYNAME}.der" ]] ; then + # If the public key (certificate) has already been enrolled in the UEFI, append "_enrolled" to the suffix of the backup file. + # Note: `mokutil --help` fails if EFI variables are not supported on the system. + # If it is impossible to ascertain if the MOK is enrolled in the UEFI, do not add the "_enrolled" suffix to the backup file. + if command -v mokutil && mokutil --test-key "${PUBLIC_KEY_DIR}/${KEYNAME}.der" &>/dev/null; then + KEY_SUFFIX="${KEY_SUFFIX}_enrolled" + fi - # Rename the existing private key with the conflicting name. - if [[ -e "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" ]] ; then - mv "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" "${PRIVATE_KEY_DIR}/${KEYNAME}.priv.${KEY_SUFFIX}.bak" - fi - fi + # Rename the existing public key with the conflicting name. + mv "${PUBLIC_KEY_DIR}/${KEYNAME}.der" "${PUBLIC_KEY_DIR}/${KEYNAME}.der.${KEY_SUFFIX}.bak" + + # Rename the existing private key with the conflicting name. + if [[ -e "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" ]] ; then + mv "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" "${PRIVATE_KEY_DIR}/${KEYNAME}.priv.${KEY_SUFFIX}.bak" + fi + fi } function create_new_keypair() { - echo "CREATING NEW KEY PAIR..." + echo "CREATING NEW KEY PAIR..." - # Prepare an OpenSSL command to generate the key pair. - local keypair_generation_command=( - "openssl req" # Request new certificate - "-x509" # X.509 certificate type - "-new" # New key pair - "-nodes" # No DES - "-utf8" # UTF-8 encoding - "-sha256" # SHA-256 hash algorithm - "-days" "3650" # 10 year cert validity - "${AUTOMATIC_BUILD_OPTION}" # Empty or "-batch" - "-config" "${CACERT_CONFIG_PATH}" # Configuration file path - "-outform" "DER" # DER output format - "-out" "${PUBLIC_KEY_DIR}/${KEYNAME}.der" # Public key output path - "-keyout" "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" # Private key output path - ) + # Prepare an OpenSSL command to generate the key pair. + local keypair_generation_command=( + "openssl req" # Request new certificate + "-x509" # X.509 certificate type + "-new" # New key pair + "-nodes" # No DES + "-utf8" # UTF-8 encoding + "-sha256" # SHA-256 hash algorithm + "-days" "3650" # 10 year cert validity + "${AUTOMATIC_BUILD_OPTION}" # Empty or "-batch" + "-config" "${CACERT_CONFIG_PATH}" # Configuration file path + "-outform" "DER" # DER output format + "-out" "${PUBLIC_KEY_DIR}/${KEYNAME}.der" # Public key output path + "-keyout" "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" # Private key output path + ) - # Execute the key pair generation command within the 'akmods' group context. - # Ensure 'rw-rwx---' permissions. - sg akmods -c "umask 037 && ${keypair_generation_command[*]}" + # Execute the key pair generation command within the 'akmods' group context. + # Ensure 'rw-rwx---' permissions. + sg akmods -c "umask 037 && ${keypair_generation_command[*]}" } function set_key_permissions() { # Ensure that akmods group can read keys. - chmod g+r "${PUBLIC_KEY_DIR}/${KEYNAME}.*" - chmod g+r "${PRIVATE_KEY_DIR}/${KEYNAME}.*" + chmod g+r "${PUBLIC_KEY_DIR}/${KEYNAME}.*" + chmod g+r "${PRIVATE_KEY_DIR}/${KEYNAME}.*" # Sanitise permissions. - if [[ -x "$RESTORECON_PATH" ]] ; then - $RESTORECON_PATH "${PUBLIC_KEY_DIR}/${KEYNAME}.der" - $RESTORECON_PATH "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" - fi + if [[ -x "$RESTORECON_PATH" ]] ; then + $RESTORECON_PATH "${PUBLIC_KEY_DIR}/${KEYNAME}.der" + $RESTORECON_PATH "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" + fi } function update_key_symlinks() { - ln -nsf "${PUBLIC_KEY_DIR}/${KEYNAME}.der" "$PUBLIC_KEY_PATH" - ln -nsf "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" "$PRIVATE_KEY_PATH" + ln -nsf "${PUBLIC_KEY_DIR}/${KEYNAME}.der" "$PUBLIC_KEY_PATH" + ln -nsf "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" "$PRIVATE_KEY_PATH" } # SCRIPT MAINLINE From c53884d73f3dc7aac39922c4aef0d7949163fe1c Mon Sep 17 00:00:00 2001 From: Rohan Barar Date: Fri, 20 Sep 2024 19:48:58 +1000 Subject: [PATCH 28/79] Added error handling for failed cacert modification. --- akmods-kmodgenca | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/akmods-kmodgenca b/akmods-kmodgenca index e47bd4b..04cfbf1 100644 --- a/akmods-kmodgenca +++ b/akmods-kmodgenca @@ -30,6 +30,7 @@ # 0 - SUCCESS # 1 - INVALID ARGUMENT # 2 - BROKEN EXISTING KEY PAIR +# 3 - CA CERT CONFIG MODIFICATION FAILED # DECLARE CONSTANTS # Script Information @@ -150,6 +151,9 @@ function check_existing_key_pair() { function create_ca_cert_config() { echo "UPDATING '${CACERT_CONFIG_PATH}'..." if [ "$AUTOMATIC_BUILD" -eq 1 ]; then + # Set '-batch' argument. + AUTOMATIC_BUILD_OPTION="-batch" + # Utilise default values if 'AUTOMATIC_BUILD' is equal to '1'. # Set OpenSSL field values. # Comment default and min/max values. @@ -163,12 +167,19 @@ function create_ca_cert_config() { -e "s/^[^#]*_default *= /#&/" \ -e "s/^[^#]*_min/#&/" \ -e "s/^[^#]*_max/#&/" "${CACERT_CONFIG_PATH}.in" > "$CACERT_CONFIG_PATH" - AUTOMATIC_BUILD_OPTION="-batch" else # Request user enter values manually if 'AUTOMATIC_BUILD' is equal to '0'. # Request OpenSSL prompt user for values later. sed -e "s#\(prompt *= \).*#\1yes#" "${CACERT_CONFIG_PATH}.in" > "$CACERT_CONFIG_PATH" fi + + # Check if 'sed' command failed. + if [ $? -ne 0 ]; then + echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} CACERT CONFIG FILE MODIFICATION FAILED." + echo "Failed to update the CA certificate configuration file at '${CACERT_CONFIG_PATH}'." + echo "Quitting." + exit 3 + fi } function backup_existing_key_pair() { From de9240959fbe4a52b44021243a622c7e3f569be1 Mon Sep 17 00:00:00 2001 From: Rohan Barar Date: Fri, 20 Sep 2024 21:20:02 +1000 Subject: [PATCH 29/79] Improved mokutil error handling + Added sudo prefixes. --- akmods-kmodgenca | 72 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 50 insertions(+), 22 deletions(-) diff --git a/akmods-kmodgenca b/akmods-kmodgenca index 04cfbf1..f83865f 100644 --- a/akmods-kmodgenca +++ b/akmods-kmodgenca @@ -26,7 +26,7 @@ # SOFTWARE. ################################################################################ -# EXIT STATUSES +# EXIT STATUS LOOKUP # 0 - SUCCESS # 1 - INVALID ARGUMENT # 2 - BROKEN EXISTING KEY PAIR @@ -109,16 +109,15 @@ function check_broken_key_pair() { # 2. A forced rebuild was not requested (i.e., 'FORCE_BUILD' is NOT '1') # shellcheck disable=SC2155 - local pub_key_exists=$(readlink -e "$PUBLIC_KEY_PATH" &>/dev/null && echo 1 || echo 0) + local pub_key_exists=$(sudo readlink -e "$PUBLIC_KEY_PATH" &>/dev/null && echo 1 || echo 0) # shellcheck disable=SC2155 - local pri_key_exists=$(readlink -e "$PRIVATE_KEY_PATH" &>/dev/null && echo 1 || echo 0) + local pri_key_exists=$(sudo readlink -e "$PRIVATE_KEY_PATH" &>/dev/null && echo 1 || echo 0) if [[ "$pub_key_exists" -ne "$pri_key_exists" && "$FORCE_BUILD" -eq 0 ]]; then # Notify user. echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} BROKEN EXISTING KEY PAIR." echo "Both a public key and a private key must exist." - echo "Currently, only a single key is present." # Dynamic status output with colours. echo -e " ${PUBLIC_KEY_PATH}: $( [[ $pub_key_exists -eq 1 ]] && echo -e "${BOLD_GREEN_TEXT}PRESENT${CLEAR_TEXT}" || echo -e "${BOLD_RED_TEXT}MISSING${CLEAR_TEXT}" )" @@ -134,8 +133,8 @@ function check_existing_key_pair() { # Terminate the script when: # 1. Both a certificate (public key) and private key already exist, AND # 2. A forced rebuild was not requested (i.e., 'FORCE_BUILD' is NOT '1') - if readlink -e "$PUBLIC_KEY_PATH" &>/dev/null && \ - readlink -e "$PRIVATE_KEY_PATH" &>/dev/null && \ + if sudo readlink -e "$PUBLIC_KEY_PATH" &>/dev/null && \ + sudo readlink -e "$PRIVATE_KEY_PATH" &>/dev/null && \ [ "$FORCE_BUILD" -eq 0 ]; then # Notify user. @@ -154,10 +153,13 @@ function create_ca_cert_config() { # Set '-batch' argument. AUTOMATIC_BUILD_OPTION="-batch" + # Initialise output variable. + local sed_output="" + # Utilise default values if 'AUTOMATIC_BUILD' is equal to '1'. # Set OpenSSL field values. # Comment default and min/max values. - sed -e "s#\(0.organizationName *= \).*#\1$(hostname)#" \ + sed_output=$(sudo sed -e "s#\(0.organizationName *= \).*#\1$(hostname)#" \ -e "s#\(organizationalUnitName *= \).*#\1$(hostname)#" \ -e "s#\(emailAddress *= \).*#\1akmods@$(hostname)#" \ -e "s#\(localityName *= \).*#\1None#" \ @@ -166,15 +168,17 @@ function create_ca_cert_config() { -e "s#\(commonName *= \).*#\1${KEYNAME}#" \ -e "s/^[^#]*_default *= /#&/" \ -e "s/^[^#]*_min/#&/" \ - -e "s/^[^#]*_max/#&/" "${CACERT_CONFIG_PATH}.in" > "$CACERT_CONFIG_PATH" + -e "s/^[^#]*_max/#&/" "${CACERT_CONFIG_PATH}.in" 2>&1 | sudo tee "$CACERT_CONFIG_PATH" > /dev/null) else # Request user enter values manually if 'AUTOMATIC_BUILD' is equal to '0'. # Request OpenSSL prompt user for values later. - sed -e "s#\(prompt *= \).*#\1yes#" "${CACERT_CONFIG_PATH}.in" > "$CACERT_CONFIG_PATH" + sed_output=$(sudo sed -e "s#\(prompt *= \).*#\1yes#" "${CACERT_CONFIG_PATH}.in" | sudo tee "$CACERT_CONFIG_PATH" > /dev/null) fi # Check if 'sed' command failed. - if [ $? -ne 0 ]; then + # shellcheck disable=SC2181 + if [ "$?" -ne 0 ]; then + echo "$sed_output" echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} CACERT CONFIG FILE MODIFICATION FAILED." echo "Failed to update the CA certificate configuration file at '${CACERT_CONFIG_PATH}'." echo "Quitting." @@ -186,18 +190,34 @@ function backup_existing_key_pair() { # Check if the randomly-generated key pair name conflicts with an existing pair. if [[ -e "${PUBLIC_KEY_DIR}/${KEYNAME}.der" ]] ; then # If the public key (certificate) has already been enrolled in the UEFI, append "_enrolled" to the suffix of the backup file. + # As per 'mokutil/src/mokutil.c' @ https://src.fedoraproject.org/rpms/mokutil.git: + # -1 (255) : General Error. + # 0 : Key Not Enrolled. + # 1 : Key Enrolled. # Note: `mokutil --help` fails if EFI variables are not supported on the system. # If it is impossible to ascertain if the MOK is enrolled in the UEFI, do not add the "_enrolled" suffix to the backup file. - if command -v mokutil && mokutil --test-key "${PUBLIC_KEY_DIR}/${KEYNAME}.der" &>/dev/null; then - KEY_SUFFIX="${KEY_SUFFIX}_enrolled" - fi + if command -v mokutil &>/dev/null; then + local mokutil_output="" + local mokutil_exit_status=0 + mokutil_output=$(sudo mokutil --test-key "${PUBLIC_KEY_DIR}/${KEYNAME}.der" 2>&1) + mokutil_exit_status="$?" + + if [[ "$mokutil_exit_status" -eq 1 ]]; then + KEY_SUFFIX="${KEY_SUFFIX}_enrolled" + elif [[ "$mokutil_exit_status" -ne 0 ]]; then + echo "$mokutil_output" + echo -e "${BOLD_YELLOW_TEXT}WARNING:${CLEAR_TEXT} FAILED TO CHECK CERTIFICATE ENROLLMENT STATUS." + echo "Failed to query whether the existing public key (certificate) at '${PUBLIC_KEY_DIR}/${KEYNAME}.der' is already enrolled." + echo "Proceeding without appending '_enrolled' to key pair backup." + fi + fi # Rename the existing public key with the conflicting name. - mv "${PUBLIC_KEY_DIR}/${KEYNAME}.der" "${PUBLIC_KEY_DIR}/${KEYNAME}.der.${KEY_SUFFIX}.bak" + sudo mv "${PUBLIC_KEY_DIR}/${KEYNAME}.der" "${PUBLIC_KEY_DIR}/${KEYNAME}.der.${KEY_SUFFIX}.bak" # Rename the existing private key with the conflicting name. if [[ -e "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" ]] ; then - mv "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" "${PRIVATE_KEY_DIR}/${KEYNAME}.priv.${KEY_SUFFIX}.bak" + sudo mv "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" "${PRIVATE_KEY_DIR}/${KEYNAME}.priv.${KEY_SUFFIX}.bak" fi fi } @@ -223,24 +243,24 @@ function create_new_keypair() { # Execute the key pair generation command within the 'akmods' group context. # Ensure 'rw-rwx---' permissions. - sg akmods -c "umask 037 && ${keypair_generation_command[*]}" + sudo sg akmods -c "umask 037 && ${keypair_generation_command[*]}" } function set_key_permissions() { # Ensure that akmods group can read keys. - chmod g+r "${PUBLIC_KEY_DIR}/${KEYNAME}.*" - chmod g+r "${PRIVATE_KEY_DIR}/${KEYNAME}.*" + sudo chmod g+r "${PUBLIC_KEY_DIR}/${KEYNAME}.der" + sudo chmod g+r "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" # Sanitise permissions. if [[ -x "$RESTORECON_PATH" ]] ; then - $RESTORECON_PATH "${PUBLIC_KEY_DIR}/${KEYNAME}.der" - $RESTORECON_PATH "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" + sudo $RESTORECON_PATH "${PUBLIC_KEY_DIR}/${KEYNAME}.der" + sudo $RESTORECON_PATH "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" fi } function update_key_symlinks() { - ln -nsf "${PUBLIC_KEY_DIR}/${KEYNAME}.der" "$PUBLIC_KEY_PATH" - ln -nsf "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" "$PRIVATE_KEY_PATH" + sudo ln -nsf "${PUBLIC_KEY_DIR}/${KEYNAME}.der" "$PUBLIC_KEY_PATH" + sudo ln -nsf "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" "$PRIVATE_KEY_PATH" } # SCRIPT MAINLINE @@ -268,5 +288,13 @@ set_key_permissions # Update symlink to use new keypair. update_key_symlinks +# Print completion messages. +echo -e "${BOLD_GREEN_TEXT}SUCCESS!${CLEAR_TEST}" +echo "Public Key (Certificate) created at: ${PUBLIC}/${KEYNAME}.der" +echo "Private Key created at: ${PRIVATE_KEY_DIR}/${KEYNAME}.priv" +echo -e "\nSymlinks:" +echo "${KEYNAME}.der --> ${PUBLIC_KEY_PATH}" +echo "${KEYNAME}.priv --> ${PRIVATE_KEY_PATH}" + # Exit script. exit 0 From 04491175d2ee60261fda923035fbc846295930bf Mon Sep 17 00:00:00 2001 From: Rohan Barar Date: Fri, 20 Sep 2024 21:46:11 +1000 Subject: [PATCH 30/79] Added support for combined single-letter arguments + Chowned symlinks. --- akmods-kmodgenca | 109 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 74 insertions(+), 35 deletions(-) diff --git a/akmods-kmodgenca b/akmods-kmodgenca index f83865f..97f071b 100644 --- a/akmods-kmodgenca +++ b/akmods-kmodgenca @@ -1,7 +1,7 @@ #!/usr/bin/env bash # NAME: 'kmodgenca' -# PURPOSE: Helper script to create CA/Keypair to sign modules. +# PURPOSE: Helper script to create CA/key pair to sign modules. # Copyright (c) 2017 Stanislas Leduc # Copyright (c) 2018-2019 Nicolas Viéville # Copyright (c) 2024 Rohan Barar @@ -28,9 +28,9 @@ # EXIT STATUS LOOKUP # 0 - SUCCESS -# 1 - INVALID ARGUMENT +# 1 - INVALID COMMAND LINE ARGUMENT # 2 - BROKEN EXISTING KEY PAIR -# 3 - CA CERT CONFIG MODIFICATION FAILED +# 3 - CA CERTIFICATE CONFIGURATION MODIFICATION FAILED # DECLARE CONSTANTS # Script Information @@ -67,10 +67,12 @@ KEY_SUFFIX="$(date "+%F_%T_%N")" # FUNCTIONS function help() { echo "Creates a Certificate Authority (CA) and key pair for module signing." + echo "Private keys are created in: '${PRIVATE_KEY_DIR}'." + echo "Public keys (certificates) are created in: '${PUBLIC_KEY_DIR}'." echo -e "\nUsage: ${SCRIPT_NAME} [OPTIONS]" echo -e "\nOptions:" echo " -a, --auto Utilise default values for 'cacert.config'." - echo " -f, --force Create CA/Keypair even if one already exists." + echo " -f, --force Create CA/key pair even if one already exists." echo " -h, --help Display this help message." echo " -V, --version Display script version information." } @@ -94,13 +96,45 @@ function parse_arguments() { echo "${SCRIPT_NAME} v${SCRIPT_VERSION}" exit 0 ;; + -*) + # Handle combined single-letter options. + for (( i=1; i<${#1}; i++ )); do + case "${1:$i:1}" in + a) + AUTOMATIC_BUILD=1 + ;; + f) + FORCE_BUILD=1 + ;; + h) + help + exit 0 + ;; + V) + echo "${SCRIPT_NAME} v${SCRIPT_VERSION}" + exit 0 + ;; + *) + echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} INVALID OPTION '${1}'.\n" >&2 + help >&2 + exit 1 + ;; + esac + done + shift + ;; *) - echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} INVALID OPTION '${1}'." >&2 + echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} INVALID OPTION '${1}'.\n" >&2 help >&2 exit 1 ;; esac done + + # Warn user. + if [[ "$FORCE_BUILD" -eq 1 ]]; then + echo -e "${BOLD_YELLOW_TEXT}WARNING:${CLEAR_TEXT} FORCED BUILD SELECTED. MOK OVERWRITE MAY OCCUR!" + fi } function check_broken_key_pair() { @@ -108,6 +142,7 @@ function check_broken_key_pair() { # 1. A certificate (public key) OR private key exists (but not both), AND # 2. A forced rebuild was not requested (i.e., 'FORCE_BUILD' is NOT '1') + # Note: This approach will also detect broken symlinks (i.e., return 0). # shellcheck disable=SC2155 local pub_key_exists=$(sudo readlink -e "$PUBLIC_KEY_PATH" &>/dev/null && echo 1 || echo 0) @@ -133,6 +168,8 @@ function check_existing_key_pair() { # Terminate the script when: # 1. Both a certificate (public key) and private key already exist, AND # 2. A forced rebuild was not requested (i.e., 'FORCE_BUILD' is NOT '1') + + # Note: This approach will return '1' in the event of a broken symlink. if sudo readlink -e "$PUBLIC_KEY_PATH" &>/dev/null && \ sudo readlink -e "$PRIVATE_KEY_PATH" &>/dev/null && \ [ "$FORCE_BUILD" -eq 0 ]; then @@ -153,13 +190,13 @@ function create_ca_cert_config() { # Set '-batch' argument. AUTOMATIC_BUILD_OPTION="-batch" - # Initialise output variable. - local sed_output="" + # Initialise output variable. + local sed_output="" # Utilise default values if 'AUTOMATIC_BUILD' is equal to '1'. # Set OpenSSL field values. # Comment default and min/max values. - sed_output=$(sudo sed -e "s#\(0.organizationName *= \).*#\1$(hostname)#" \ + sed_output=$(sudo sed -e "s#\(0.organizationName *= \).*#\1$(hostname)#" \ -e "s#\(organizationalUnitName *= \).*#\1$(hostname)#" \ -e "s#\(emailAddress *= \).*#\1akmods@$(hostname)#" \ -e "s#\(localityName *= \).*#\1None#" \ @@ -176,9 +213,9 @@ function create_ca_cert_config() { fi # Check if 'sed' command failed. - # shellcheck disable=SC2181 + # shellcheck disable=SC2181 if [ "$?" -ne 0 ]; then - echo "$sed_output" + echo "$sed_output" echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} CACERT CONFIG FILE MODIFICATION FAILED." echo "Failed to update the CA certificate configuration file at '${CACERT_CONFIG_PATH}'." echo "Quitting." @@ -190,27 +227,27 @@ function backup_existing_key_pair() { # Check if the randomly-generated key pair name conflicts with an existing pair. if [[ -e "${PUBLIC_KEY_DIR}/${KEYNAME}.der" ]] ; then # If the public key (certificate) has already been enrolled in the UEFI, append "_enrolled" to the suffix of the backup file. - # As per 'mokutil/src/mokutil.c' @ https://src.fedoraproject.org/rpms/mokutil.git: - # -1 (255) : General Error. - # 0 : Key Not Enrolled. - # 1 : Key Enrolled. + # As per 'mokutil/src/mokutil.c' @ https://src.fedoraproject.org/rpms/mokutil.git: + # -1 (255) : General Error. + # 0 : Key Not Enrolled. + # 1 : Key Enrolled. # Note: `mokutil --help` fails if EFI variables are not supported on the system. # If it is impossible to ascertain if the MOK is enrolled in the UEFI, do not add the "_enrolled" suffix to the backup file. if command -v mokutil &>/dev/null; then - local mokutil_output="" - local mokutil_exit_status=0 - mokutil_output=$(sudo mokutil --test-key "${PUBLIC_KEY_DIR}/${KEYNAME}.der" 2>&1) - mokutil_exit_status="$?" + local mokutil_output="" + local mokutil_exit_status=0 + mokutil_output=$(sudo mokutil --test-key "${PUBLIC_KEY_DIR}/${KEYNAME}.der" 2>&1) + mokutil_exit_status="$?" - if [[ "$mokutil_exit_status" -eq 1 ]]; then - KEY_SUFFIX="${KEY_SUFFIX}_enrolled" - elif [[ "$mokutil_exit_status" -ne 0 ]]; then - echo "$mokutil_output" - echo -e "${BOLD_YELLOW_TEXT}WARNING:${CLEAR_TEXT} FAILED TO CHECK CERTIFICATE ENROLLMENT STATUS." - echo "Failed to query whether the existing public key (certificate) at '${PUBLIC_KEY_DIR}/${KEYNAME}.der' is already enrolled." - echo "Proceeding without appending '_enrolled' to key pair backup." - fi - fi + if [[ "$mokutil_exit_status" -eq 1 ]]; then + KEY_SUFFIX="${KEY_SUFFIX}_enrolled" + elif [[ "$mokutil_exit_status" -ne 0 ]]; then + echo "$mokutil_output" + echo -e "${BOLD_YELLOW_TEXT}WARNING:${CLEAR_TEXT} FAILED TO CHECK CERTIFICATE ENROLLMENT STATUS." + echo "Failed to query whether the existing public key (certificate) at '${PUBLIC_KEY_DIR}/${KEYNAME}.der' is already enrolled." + echo "Proceeding without appending '_enrolled' to key pair backup." + fi + fi # Rename the existing public key with the conflicting name. sudo mv "${PUBLIC_KEY_DIR}/${KEYNAME}.der" "${PUBLIC_KEY_DIR}/${KEYNAME}.der.${KEY_SUFFIX}.bak" @@ -222,11 +259,11 @@ function backup_existing_key_pair() { fi } -function create_new_keypair() { +function create_new_key_pair() { echo "CREATING NEW KEY PAIR..." # Prepare an OpenSSL command to generate the key pair. - local keypair_generation_command=( + local key_pair_generation_command=( "openssl req" # Request new certificate "-x509" # X.509 certificate type "-new" # New key pair @@ -243,7 +280,7 @@ function create_new_keypair() { # Execute the key pair generation command within the 'akmods' group context. # Ensure 'rw-rwx---' permissions. - sudo sg akmods -c "umask 037 && ${keypair_generation_command[*]}" + sudo sg akmods -c "umask 037 && ${key_pair_generation_command[*]}" } function set_key_permissions() { @@ -261,6 +298,8 @@ function set_key_permissions() { function update_key_symlinks() { sudo ln -nsf "${PUBLIC_KEY_DIR}/${KEYNAME}.der" "$PUBLIC_KEY_PATH" sudo ln -nsf "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" "$PRIVATE_KEY_PATH" + sudo chown -h root:akmods "$PUBLIC_KEY_PATH" + sudo chown -h root:akmods "$PRIVATE_KEY_PATH" } # SCRIPT MAINLINE @@ -279,18 +318,18 @@ create_ca_cert_config # Avoid overwriting key pairs with the same randomly-generated name. backup_existing_key_pair -# Create new keypair. -create_new_keypair +# Create new key pair. +create_new_key_pair # Set permissions and sanitise keys. set_key_permissions -# Update symlink to use new keypair. +# Update symlink to use new key pair. update_key_symlinks # Print completion messages. -echo -e "${BOLD_GREEN_TEXT}SUCCESS!${CLEAR_TEST}" -echo "Public Key (Certificate) created at: ${PUBLIC}/${KEYNAME}.der" +echo -e "\n${BOLD_GREEN_TEXT}SUCCESS!${CLEAR_TEXT}" +echo "Public Key (Certificate) created at: ${PUBLIC_KEY_DIR}/${KEYNAME}.der" echo "Private Key created at: ${PRIVATE_KEY_DIR}/${KEYNAME}.priv" echo -e "\nSymlinks:" echo "${KEYNAME}.der --> ${PUBLIC_KEY_PATH}" From d69af03966a081a95a121c9c6b010e8bf5b3ffc1 Mon Sep 17 00:00:00 2001 From: Rohan Barar Date: Sat, 21 Sep 2024 02:57:22 +1000 Subject: [PATCH 31/79] Revert "Utilise robust shebang." as per request on PR #23. This reverts commit cf80933cec2e50333bd1f846f38c99d814556b9b. --- akmods-kmodgenca | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/akmods-kmodgenca b/akmods-kmodgenca index 97f071b..3d388bf 100644 --- a/akmods-kmodgenca +++ b/akmods-kmodgenca @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/bin/bash # NAME: 'kmodgenca' # PURPOSE: Helper script to create CA/key pair to sign modules. From 4864888a4ca8546e8e2cd24c6d9fe4cfa2a76016 Mon Sep 17 00:00:00 2001 From: Rohan Barar Date: Sat, 21 Sep 2024 06:43:47 +1000 Subject: [PATCH 32/79] Improved clarity of exit status code comments. --- akmods-kmodgenca | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/akmods-kmodgenca b/akmods-kmodgenca index 3d388bf..fc61205 100644 --- a/akmods-kmodgenca +++ b/akmods-kmodgenca @@ -26,7 +26,7 @@ # SOFTWARE. ################################################################################ -# EXIT STATUS LOOKUP +# EXIT STATUS CODES AND DESCRIPTIONS # 0 - SUCCESS # 1 - INVALID COMMAND LINE ARGUMENT # 2 - BROKEN EXISTING KEY PAIR From 9eda4f0d735e47bb36d17bce409f85585f6c36a8 Mon Sep 17 00:00:00 2001 From: Rohan Barar Date: Sat, 21 Sep 2024 15:59:35 +1000 Subject: [PATCH 33/79] Further improvements to argument parsing logic. --- akmods-kmodgenca | 67 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 52 insertions(+), 15 deletions(-) diff --git a/akmods-kmodgenca b/akmods-kmodgenca index fc61205..e45a4c8 100644 --- a/akmods-kmodgenca +++ b/akmods-kmodgenca @@ -56,16 +56,24 @@ readonly RESTORECON_PATH="/usr/sbin/restorecon" readonly BOLD_RED_TEXT="\e[1;31m" readonly BOLD_YELLOW_TEXT="\e[1;33m" readonly BOLD_GREEN_TEXT="\033[1;32m" +readonly BOLD_GREY_TEXT="\e[1;37m" readonly CLEAR_TEXT="\e[0m" # DECLARE VARIABLES +# Command Line Argument Flags FORCE_BUILD=0 AUTOMATIC_BUILD=0 +SHOW_HELP=0 +SHOW_VER=0 +BAD_ARGS=0 + +# Other AUTOMATIC_BUILD_OPTION="" KEY_SUFFIX="$(date "+%F_%T_%N")" # FUNCTIONS function help() { + echo -e "${BOLD_GREY_TEXT}KMODGENCA HELP${CLEAR_TEXT}" echo "Creates a Certificate Authority (CA) and key pair for module signing." echo "Private keys are created in: '${PRIVATE_KEY_DIR}'." echo "Public keys (certificates) are created in: '${PUBLIC_KEY_DIR}'." @@ -75,6 +83,7 @@ function help() { echo " -f, --force Create CA/key pair even if one already exists." echo " -h, --help Display this help message." echo " -V, --version Display script version information." + echo "" } function parse_arguments() { @@ -89,12 +98,12 @@ function parse_arguments() { shift ;; -h|--help) - help - exit 0 + SHOW_HELP=1 + shift ;; -V|--version) - echo "${SCRIPT_NAME} v${SCRIPT_VERSION}" - exit 0 + SHOW_VER=1 + shift ;; -*) # Handle combined single-letter options. @@ -107,34 +116,62 @@ function parse_arguments() { FORCE_BUILD=1 ;; h) - help - exit 0 + SHOW_HELP=1 ;; V) - echo "${SCRIPT_NAME} v${SCRIPT_VERSION}" - exit 0 + SHOW_VER=1 ;; *) - echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} INVALID OPTION '${1}'.\n" >&2 - help >&2 - exit 1 + echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} INVALID OPTION '${1:$i:1}' in '${1}'." >&2 + BAD_ARGS=1 ;; esac done shift ;; *) - echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} INVALID OPTION '${1}'.\n" >&2 - help >&2 - exit 1 + echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} INVALID OPTION '${1}'." >&2 + BAD_ARGS=1 + shift ;; esac done - # Warn user. + # Display help message and then exit in the event of invalid command line argument(s). + if [[ "$BAD_ARGS" -eq 1 ]]; then + echo -en "\n" + help >&2 + exit 1 + fi + + # Display script help information if requested. + if [[ "$SHOW_HELP" -eq 1 ]]; then + help + fi + + # Display script version information if requested. + if [[ "$SHOW_VER" -eq 1 ]]; then + "${SCRIPT_NAME} v${SCRIPT_VERSION}" + fi + + # Exit script if version and/or help information requested. + if [ "$SHOW_VER" -eq 1 ] || [ "$SHOW_HELP" -eq 1 ]; then + if [ "$AUTOMATIC_BUILD" -eq 1 ] || [ "$FORCE_BUILD" -eq 1 ]; then + # Display warning regarding ignoring additional arguments due to displaying help and/or version information. + echo -e "${BOLD_YELLOW_TEXT}WARNING:${CLEAR_TEXT} IGNORING ADDITIONAL ARGUMENTS AS HELP AND/OR VERSION INFORMATION REQUESTED." + fi + exit 0 + fi + + # Warn user regarding forced builds. if [[ "$FORCE_BUILD" -eq 1 ]]; then echo -e "${BOLD_YELLOW_TEXT}WARNING:${CLEAR_TEXT} FORCED BUILD SELECTED. MOK OVERWRITE MAY OCCUR!" fi + + # Warn user regarding automatic builds. + if [[ "$AUTOMATIC_BUILD" -eq 1 ]]; then + echo -e "${BOLD_YELLOW_TEXT}WARNING:${CLEAR_TEXT} AUTOMATIC BUILD SELECTED. USING DEFAULT VALUES FOR CA/KEY PAIR CREATION." + fi } function check_broken_key_pair() { From aa859af678da8d48dac23c9f08ff7145c8fe16a1 Mon Sep 17 00:00:00 2001 From: Rohan Barar Date: Sun, 22 Sep 2024 00:09:40 +1000 Subject: [PATCH 34/79] Removed 'sudo' prefixes as per request in PR #23. --- akmods-kmodgenca | 53 ++++++++++++++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/akmods-kmodgenca b/akmods-kmodgenca index e45a4c8..ab57e85 100644 --- a/akmods-kmodgenca +++ b/akmods-kmodgenca @@ -180,11 +180,13 @@ function check_broken_key_pair() { # 2. A forced rebuild was not requested (i.e., 'FORCE_BUILD' is NOT '1') # Note: This approach will also detect broken symlinks (i.e., return 0). + # Note: Requires superuser permissions (i.e. sudo). # shellcheck disable=SC2155 - local pub_key_exists=$(sudo readlink -e "$PUBLIC_KEY_PATH" &>/dev/null && echo 1 || echo 0) + local pub_key_exists=$(readlink -e "$PUBLIC_KEY_PATH" &>/dev/null && echo 1 || echo 0) + # Note: Requires superuser permissions (i.e. sudo). # shellcheck disable=SC2155 - local pri_key_exists=$(sudo readlink -e "$PRIVATE_KEY_PATH" &>/dev/null && echo 1 || echo 0) + local pri_key_exists=$(readlink -e "$PRIVATE_KEY_PATH" &>/dev/null && echo 1 || echo 0) if [[ "$pub_key_exists" -ne "$pri_key_exists" && "$FORCE_BUILD" -eq 0 ]]; then # Notify user. @@ -207,9 +209,10 @@ function check_existing_key_pair() { # 2. A forced rebuild was not requested (i.e., 'FORCE_BUILD' is NOT '1') # Note: This approach will return '1' in the event of a broken symlink. - if sudo readlink -e "$PUBLIC_KEY_PATH" &>/dev/null && \ - sudo readlink -e "$PRIVATE_KEY_PATH" &>/dev/null && \ - [ "$FORCE_BUILD" -eq 0 ]; then + # Note: Requires superuser permissions (i.e. sudo). + if readlink -e "$PUBLIC_KEY_PATH" &>/dev/null && \ + readlink -e "$PRIVATE_KEY_PATH" &>/dev/null && \ + [ "$FORCE_BUILD" -eq 0 ]; then # Notify user. echo -e "${BOLD_YELLOW_TEXT}WARNING:${CLEAR_TEXT} EXISTING KEY PAIR." @@ -233,7 +236,8 @@ function create_ca_cert_config() { # Utilise default values if 'AUTOMATIC_BUILD' is equal to '1'. # Set OpenSSL field values. # Comment default and min/max values. - sed_output=$(sudo sed -e "s#\(0.organizationName *= \).*#\1$(hostname)#" \ + # Note: Requires superuser permissions (i.e. sudo). + sed_output=$(sed -e "s#\(0.organizationName *= \).*#\1$(hostname)#" \ -e "s#\(organizationalUnitName *= \).*#\1$(hostname)#" \ -e "s#\(emailAddress *= \).*#\1akmods@$(hostname)#" \ -e "s#\(localityName *= \).*#\1None#" \ @@ -242,11 +246,12 @@ function create_ca_cert_config() { -e "s#\(commonName *= \).*#\1${KEYNAME}#" \ -e "s/^[^#]*_default *= /#&/" \ -e "s/^[^#]*_min/#&/" \ - -e "s/^[^#]*_max/#&/" "${CACERT_CONFIG_PATH}.in" 2>&1 | sudo tee "$CACERT_CONFIG_PATH" > /dev/null) + -e "s/^[^#]*_max/#&/" "${CACERT_CONFIG_PATH}.in" 2>&1 | tee "$CACERT_CONFIG_PATH" > /dev/null) else # Request user enter values manually if 'AUTOMATIC_BUILD' is equal to '0'. # Request OpenSSL prompt user for values later. - sed_output=$(sudo sed -e "s#\(prompt *= \).*#\1yes#" "${CACERT_CONFIG_PATH}.in" | sudo tee "$CACERT_CONFIG_PATH" > /dev/null) + # Note: Requires superuser permissions (i.e. sudo). + sed_output=$(sed -e "s#\(prompt *= \).*#\1yes#" "${CACERT_CONFIG_PATH}.in" | tee "$CACERT_CONFIG_PATH" > /dev/null) fi # Check if 'sed' command failed. @@ -273,7 +278,9 @@ function backup_existing_key_pair() { if command -v mokutil &>/dev/null; then local mokutil_output="" local mokutil_exit_status=0 - mokutil_output=$(sudo mokutil --test-key "${PUBLIC_KEY_DIR}/${KEYNAME}.der" 2>&1) + + # Note: Requires superuser permissions (i.e. sudo). + mokutil_output=$(mokutil --test-key "${PUBLIC_KEY_DIR}/${KEYNAME}.der" 2>&1) mokutil_exit_status="$?" if [[ "$mokutil_exit_status" -eq 1 ]]; then @@ -287,11 +294,13 @@ function backup_existing_key_pair() { fi # Rename the existing public key with the conflicting name. - sudo mv "${PUBLIC_KEY_DIR}/${KEYNAME}.der" "${PUBLIC_KEY_DIR}/${KEYNAME}.der.${KEY_SUFFIX}.bak" + # Note: Requires superuser permissions (i.e. sudo). + mv "${PUBLIC_KEY_DIR}/${KEYNAME}.der" "${PUBLIC_KEY_DIR}/${KEYNAME}.der.${KEY_SUFFIX}.bak" # Rename the existing private key with the conflicting name. if [[ -e "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" ]] ; then - sudo mv "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" "${PRIVATE_KEY_DIR}/${KEYNAME}.priv.${KEY_SUFFIX}.bak" + # Note: Requires superuser permissions (i.e. sudo). + mv "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" "${PRIVATE_KEY_DIR}/${KEYNAME}.priv.${KEY_SUFFIX}.bak" fi fi } @@ -317,26 +326,30 @@ function create_new_key_pair() { # Execute the key pair generation command within the 'akmods' group context. # Ensure 'rw-rwx---' permissions. - sudo sg akmods -c "umask 037 && ${key_pair_generation_command[*]}" + # Note: Requires superuser permissions (i.e. sudo). + sg akmods -c "umask 037 && ${key_pair_generation_command[*]}" } function set_key_permissions() { # Ensure that akmods group can read keys. - sudo chmod g+r "${PUBLIC_KEY_DIR}/${KEYNAME}.der" - sudo chmod g+r "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" + # Note: Requires superuser permissions (i.e. sudo). + chmod g+r "${PUBLIC_KEY_DIR}/${KEYNAME}.der" + chmod g+r "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" # Sanitise permissions. + # Note: Requires superuser permissions (i.e. sudo). if [[ -x "$RESTORECON_PATH" ]] ; then - sudo $RESTORECON_PATH "${PUBLIC_KEY_DIR}/${KEYNAME}.der" - sudo $RESTORECON_PATH "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" + $RESTORECON_PATH "${PUBLIC_KEY_DIR}/${KEYNAME}.der" + $RESTORECON_PATH "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" fi } function update_key_symlinks() { - sudo ln -nsf "${PUBLIC_KEY_DIR}/${KEYNAME}.der" "$PUBLIC_KEY_PATH" - sudo ln -nsf "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" "$PRIVATE_KEY_PATH" - sudo chown -h root:akmods "$PUBLIC_KEY_PATH" - sudo chown -h root:akmods "$PRIVATE_KEY_PATH" + # Note: Requires superuser permissions (i.e. sudo). + ln -nsf "${PUBLIC_KEY_DIR}/${KEYNAME}.der" "$PUBLIC_KEY_PATH" + ln -nsf "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" "$PRIVATE_KEY_PATH" + chown -h root:akmods "$PUBLIC_KEY_PATH" + chown -h root:akmods "$PRIVATE_KEY_PATH" } # SCRIPT MAINLINE From 797795f2fe504d531018e51b623ecf240ebfd6ea Mon Sep 17 00:00:00 2001 From: Rohan Barar Date: Sun, 22 Sep 2024 07:30:03 +1000 Subject: [PATCH 35/79] Refactor key pair naming scheme to enhance robustness + Removed collision check and key pair backup function due to bug with ':' in file names alongside superfluous nature of function given improved naming scheme. --- akmods-kmodgenca | 60 ++++++++---------------------------------------- 1 file changed, 9 insertions(+), 51 deletions(-) diff --git a/akmods-kmodgenca b/akmods-kmodgenca index ab57e85..2a61231 100644 --- a/akmods-kmodgenca +++ b/akmods-kmodgenca @@ -37,8 +37,8 @@ readonly SCRIPT_NAME="kmodgenca" readonly SCRIPT_VERSION="0.5.7" -# New Key Pair Name (Hostname + 32-Bit Unsigned Integer) -KEYNAME="$(hostname)-$(od -vAn -N4 -tu4 < /dev/urandom | awk '{print $1}')" +# Unique New Key Pair Name (Hostname + UNIX/POSIX Timestamp + Dashless UUID) +KEYNAME="$(hostname)_$(date +%s)_$(uuidgen | tr -d '-')" readonly KEYNAME # Directories @@ -69,7 +69,6 @@ BAD_ARGS=0 # Other AUTOMATIC_BUILD_OPTION="" -KEY_SUFFIX="$(date "+%F_%T_%N")" # FUNCTIONS function help() { @@ -139,7 +138,7 @@ function parse_arguments() { # Display help message and then exit in the event of invalid command line argument(s). if [[ "$BAD_ARGS" -eq 1 ]]; then - echo -en "\n" + echo "" help >&2 exit 1 fi @@ -156,16 +155,18 @@ function parse_arguments() { # Exit script if version and/or help information requested. if [ "$SHOW_VER" -eq 1 ] || [ "$SHOW_HELP" -eq 1 ]; then - if [ "$AUTOMATIC_BUILD" -eq 1 ] || [ "$FORCE_BUILD" -eq 1 ]; then - # Display warning regarding ignoring additional arguments due to displaying help and/or version information. - echo -e "${BOLD_YELLOW_TEXT}WARNING:${CLEAR_TEXT} IGNORING ADDITIONAL ARGUMENTS AS HELP AND/OR VERSION INFORMATION REQUESTED." + if [ "$AUTOMATIC_BUILD" -eq 1 ]; then + echo -e "${BOLD_YELLOW_TEXT}WARNING:${CLEAR_TEXT} IGNORING '-a' (--auto)." + fi + if [ "$FORCE_BUILD" -eq 1 ]; then + echo -e "${BOLD_YELLOW_TEXT}WARNING:${CLEAR_TEXT} IGNORING '-f' (--force)." fi exit 0 fi # Warn user regarding forced builds. if [[ "$FORCE_BUILD" -eq 1 ]]; then - echo -e "${BOLD_YELLOW_TEXT}WARNING:${CLEAR_TEXT} FORCED BUILD SELECTED. MOK OVERWRITE MAY OCCUR!" + echo -e "${BOLD_YELLOW_TEXT}WARNING:${CLEAR_TEXT} FORCED BUILD SELECTED. KEY PAIR OVERWRITE MAY OCCUR!" fi # Warn user regarding automatic builds. @@ -265,46 +266,6 @@ function create_ca_cert_config() { fi } -function backup_existing_key_pair() { - # Check if the randomly-generated key pair name conflicts with an existing pair. - if [[ -e "${PUBLIC_KEY_DIR}/${KEYNAME}.der" ]] ; then - # If the public key (certificate) has already been enrolled in the UEFI, append "_enrolled" to the suffix of the backup file. - # As per 'mokutil/src/mokutil.c' @ https://src.fedoraproject.org/rpms/mokutil.git: - # -1 (255) : General Error. - # 0 : Key Not Enrolled. - # 1 : Key Enrolled. - # Note: `mokutil --help` fails if EFI variables are not supported on the system. - # If it is impossible to ascertain if the MOK is enrolled in the UEFI, do not add the "_enrolled" suffix to the backup file. - if command -v mokutil &>/dev/null; then - local mokutil_output="" - local mokutil_exit_status=0 - - # Note: Requires superuser permissions (i.e. sudo). - mokutil_output=$(mokutil --test-key "${PUBLIC_KEY_DIR}/${KEYNAME}.der" 2>&1) - mokutil_exit_status="$?" - - if [[ "$mokutil_exit_status" -eq 1 ]]; then - KEY_SUFFIX="${KEY_SUFFIX}_enrolled" - elif [[ "$mokutil_exit_status" -ne 0 ]]; then - echo "$mokutil_output" - echo -e "${BOLD_YELLOW_TEXT}WARNING:${CLEAR_TEXT} FAILED TO CHECK CERTIFICATE ENROLLMENT STATUS." - echo "Failed to query whether the existing public key (certificate) at '${PUBLIC_KEY_DIR}/${KEYNAME}.der' is already enrolled." - echo "Proceeding without appending '_enrolled' to key pair backup." - fi - fi - - # Rename the existing public key with the conflicting name. - # Note: Requires superuser permissions (i.e. sudo). - mv "${PUBLIC_KEY_DIR}/${KEYNAME}.der" "${PUBLIC_KEY_DIR}/${KEYNAME}.der.${KEY_SUFFIX}.bak" - - # Rename the existing private key with the conflicting name. - if [[ -e "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" ]] ; then - # Note: Requires superuser permissions (i.e. sudo). - mv "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" "${PRIVATE_KEY_DIR}/${KEYNAME}.priv.${KEY_SUFFIX}.bak" - fi - fi -} - function create_new_key_pair() { echo "CREATING NEW KEY PAIR..." @@ -365,9 +326,6 @@ check_existing_key_pair # Create 'cacert.config' using template file 'cacert.config.in'. create_ca_cert_config -# Avoid overwriting key pairs with the same randomly-generated name. -backup_existing_key_pair - # Create new key pair. create_new_key_pair From 5137531fa2b090d2e397d6405d0a779911c1483e Mon Sep 17 00:00:00 2001 From: Rohan Barar Date: Mon, 23 Sep 2024 00:14:52 +1000 Subject: [PATCH 36/79] Introduced loop to gracefully handle extremely rare key pair name collision events. --- akmods-kmodgenca | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/akmods-kmodgenca b/akmods-kmodgenca index 2a61231..50f0de6 100644 --- a/akmods-kmodgenca +++ b/akmods-kmodgenca @@ -37,10 +37,6 @@ readonly SCRIPT_NAME="kmodgenca" readonly SCRIPT_VERSION="0.5.7" -# Unique New Key Pair Name (Hostname + UNIX/POSIX Timestamp + Dashless UUID) -KEYNAME="$(hostname)_$(date +%s)_$(uuidgen | tr -d '-')" -readonly KEYNAME - # Directories readonly AKMODS_DIR="/etc/pki/akmods" readonly PRIVATE_KEY_DIR="${AKMODS_DIR}/private" @@ -67,6 +63,9 @@ SHOW_HELP=0 SHOW_VER=0 BAD_ARGS=0 +# Unique New Key Pair Name (Hostname + UNIX/POSIX Timestamp + Dashless UUID) +KEYNAME="$(hostname)_$(date +%s)_$(uuidgen | tr -d '-')" + # Other AUTOMATIC_BUILD_OPTION="" @@ -227,6 +226,12 @@ function check_existing_key_pair() { function create_ca_cert_config() { echo "UPDATING '${CACERT_CONFIG_PATH}'..." + + # Handle the extremely unlikely occurrence of a key pair name conflict with an existing key pair. + while [ -f "${PUBLIC_KEY_DIR}/${KEYNAME}.der" ]; do + KEYNAME="$(hostname)_$(date +%s)_$(uuidgen | tr -d '-')" + done + if [ "$AUTOMATIC_BUILD" -eq 1 ]; then # Set '-batch' argument. AUTOMATIC_BUILD_OPTION="-batch" From f66ba44415f207e1b72e65a3e8fdb9ea01b742d5 Mon Sep 17 00:00:00 2001 From: Rohan Barar Date: Thu, 26 Sep 2024 19:00:29 +1000 Subject: [PATCH 37/79] Added ability for user to name key pair. --- akmods-kmodgenca | 60 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/akmods-kmodgenca b/akmods-kmodgenca index 50f0de6..c12b559 100644 --- a/akmods-kmodgenca +++ b/akmods-kmodgenca @@ -224,6 +224,63 @@ function check_existing_key_pair() { fi } +function request_key_pair_name() { + if [ "$AUTOMATIC_BUILD" -eq 0 ]; then + while true; do + local key_pair_file_name="" + local valid_name=1 + + read -p "Key Pair Name: " key_pair_file_name + + # Check for empty string. + if [[ -z $(echo "$key_pair_file_name" | xargs) ]]; then + valid_name=0 + echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} NAME MUST NOT BE EMPTY.\n" + fi + + # Ensure name is not '.' or '..'. + if [[ $(echo "$key_pair_file_name" | xargs) == "." ]] || [[ $(echo "$key_pair_file_name" | xargs) == ".." ]]; then + valid_name=0 + echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} NAME MUST NOT BE '.' OR '..'.\n" + fi + + # Ensure name is not longer than 255 characters. + if [ ${#$(echo "$key_pair_file_name" | xargs)} -gt 255 ]; then + valid_name=0 + echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} NAME MUST NOT BE LONGER THAN 255 CHARACTERS.\n" + fi + + # Ensure name only contains valid characters. + # - Letters (A-Z) (a-z) + # - Numbers (0-9) + # - Special + # - Period ('.') + # - Underscore ('_') + # - Hyphen ('-') + if ! [[ $(echo "$key_pair_file_name" | xargs) =~ ^[0-9a-zA-Z._-]+$ ]]; then + valid_name=0 + + # Inform user of illegal characters within provided name. + local illegal_chars=$(echo "$key_pair_file_name" | tr -cd '[^0-9a-zA-Z._-]') + echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} NAME MUST NOT CONTAIN ILLEGAL CHARACTERS." + echo -e "Illegal characters in provided name:" + for (( i=0; i<${#illegal_chars}; i++ )); do + echo "- '${illegal_chars:i:1}'" + done + echo -e "\nPlease ensure the name only contains letters, numbers, periods, underscores and hyphens.\n" + fi + + # Break the loop if a valid name was provided. + if [ "$valid_name" -eq 1 ]; then + break + fi + done + + # Update global key pair name variable. + KEYNAME="$key_pair_file_name" + fi +} + function create_ca_cert_config() { echo "UPDATING '${CACERT_CONFIG_PATH}'..." @@ -328,6 +385,9 @@ check_broken_key_pair # Check for existing key pair. check_existing_key_pair +# Request user for key pair name. +request_key_pair_name + # Create 'cacert.config' using template file 'cacert.config.in'. create_ca_cert_config From e5b0cbf2a5ca2bf8eb801324f111552aece37882 Mon Sep 17 00:00:00 2001 From: Rohan Barar Date: Thu, 26 Sep 2024 19:33:49 +1000 Subject: [PATCH 38/79] Added check for existing key pair with same name as user-specified new key pair name. --- akmods-kmodgenca | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/akmods-kmodgenca b/akmods-kmodgenca index c12b559..2cc4a2f 100644 --- a/akmods-kmodgenca +++ b/akmods-kmodgenca @@ -270,6 +270,12 @@ function request_key_pair_name() { echo -e "\nPlease ensure the name only contains letters, numbers, periods, underscores and hyphens.\n" fi + # Ensure key pair with same name does not exist. + if [ -f "${PUBLIC_KEY_DIR}/${key_pair_file_name}.der" ] || [ -f "${PRIVATE_KEY_DIR}/${key_pair_file_name}.priv" ]; then + valid_name=0 + echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} EXISTING KEY PAIR WITH SAME NAME.\n" + if + # Break the loop if a valid name was provided. if [ "$valid_name" -eq 1 ]; then break From 19ee64d82254bd48d494028d5e8c1c086ffdefe8 Mon Sep 17 00:00:00 2001 From: Rohan Barar Date: Thu, 26 Sep 2024 19:41:06 +1000 Subject: [PATCH 39/79] Fixed typo 'if' to 'fi'. --- akmods-kmodgenca | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/akmods-kmodgenca b/akmods-kmodgenca index 2cc4a2f..bf2d4cc 100644 --- a/akmods-kmodgenca +++ b/akmods-kmodgenca @@ -274,7 +274,7 @@ function request_key_pair_name() { if [ -f "${PUBLIC_KEY_DIR}/${key_pair_file_name}.der" ] || [ -f "${PRIVATE_KEY_DIR}/${key_pair_file_name}.priv" ]; then valid_name=0 echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} EXISTING KEY PAIR WITH SAME NAME.\n" - if + fi # Break the loop if a valid name was provided. if [ "$valid_name" -eq 1 ]; then From 27e2d9deb597fc87aad0fb3cd9fdea320ec52ab1 Mon Sep 17 00:00:00 2001 From: Rohan Barar Date: Thu, 26 Sep 2024 19:56:49 +1000 Subject: [PATCH 40/79] Corrected erroneous code introduced in previous commits. --- akmods-kmodgenca | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/akmods-kmodgenca b/akmods-kmodgenca index bf2d4cc..0fd4402 100644 --- a/akmods-kmodgenca +++ b/akmods-kmodgenca @@ -245,7 +245,7 @@ function request_key_pair_name() { fi # Ensure name is not longer than 255 characters. - if [ ${#$(echo "$key_pair_file_name" | xargs)} -gt 255 ]; then + if [ $(echo "$key_pair_file_name" | xargs | awk '{print length}') -gt 255 ]; then valid_name=0 echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} NAME MUST NOT BE LONGER THAN 255 CHARACTERS.\n" fi @@ -261,7 +261,7 @@ function request_key_pair_name() { valid_name=0 # Inform user of illegal characters within provided name. - local illegal_chars=$(echo "$key_pair_file_name" | tr -cd '[^0-9a-zA-Z._-]') + local illegal_chars=$(echo "$key_pair_file_name" | awk -F '' '{for(i=1;i<=NF;i++) if ($i !~ /^[0-9a-zA-Z._-]$/) print $i}' | sort -u | tr -d '\n') echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} NAME MUST NOT CONTAIN ILLEGAL CHARACTERS." echo -e "Illegal characters in provided name:" for (( i=0; i<${#illegal_chars}; i++ )); do From 6de45c936c2e71e60deed1fa6131046f0663f90b Mon Sep 17 00:00:00 2001 From: Rohan Barar Date: Thu, 26 Sep 2024 20:10:53 +1000 Subject: [PATCH 41/79] Avoid double error on empty user-provided key pair name. --- akmods-kmodgenca | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/akmods-kmodgenca b/akmods-kmodgenca index 0fd4402..e490834 100644 --- a/akmods-kmodgenca +++ b/akmods-kmodgenca @@ -258,16 +258,19 @@ function request_key_pair_name() { # - Underscore ('_') # - Hyphen ('-') if ! [[ $(echo "$key_pair_file_name" | xargs) =~ ^[0-9a-zA-Z._-]+$ ]]; then - valid_name=0 + # Avoid triggering on an empty string. + if [[ -n $(echo "$key_pair_file_name" | xargs) ]]; then + valid_name=0 - # Inform user of illegal characters within provided name. - local illegal_chars=$(echo "$key_pair_file_name" | awk -F '' '{for(i=1;i<=NF;i++) if ($i !~ /^[0-9a-zA-Z._-]$/) print $i}' | sort -u | tr -d '\n') - echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} NAME MUST NOT CONTAIN ILLEGAL CHARACTERS." - echo -e "Illegal characters in provided name:" - for (( i=0; i<${#illegal_chars}; i++ )); do - echo "- '${illegal_chars:i:1}'" - done - echo -e "\nPlease ensure the name only contains letters, numbers, periods, underscores and hyphens.\n" + # Inform user of illegal characters within provided name. + local illegal_chars=$(echo "$key_pair_file_name" | awk -F '' '{for(i=1;i<=NF;i++) if ($i !~ /^[0-9a-zA-Z._-]$/) print $i}' | sort -u | tr -d '\n') + echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} NAME MUST NOT CONTAIN ILLEGAL CHARACTERS." + echo -e "Illegal characters in provided name:" + for (( i=0; i<${#illegal_chars}; i++ )); do + echo "- '${illegal_chars:i:1}'" + done + echo -e "\nPlease ensure the name only contains letters, numbers, periods, underscores and hyphens.\n" + fi fi # Ensure key pair with same name does not exist. From 2ee741117c1dd1b491612396ab94fd72cc960a0a Mon Sep 17 00:00:00 2001 From: Nicolas Chauvet Date: Tue, 1 Oct 2024 22:15:48 +0200 Subject: [PATCH 42/79] Remove duplicate akmodsposttrans call - rhbz#2011120 --- akmods.spec | 3 --- akmodsposttrans | 47 ----------------------------------------------- 2 files changed, 50 deletions(-) delete mode 100755 akmodsposttrans diff --git a/akmods.spec b/akmods.spec index 9e33133..a3d85e1 100644 --- a/akmods.spec +++ b/akmods.spec @@ -11,7 +11,6 @@ Source0: 95-akmods.preset Source1: akmods Source2: akmodsbuild Source3: akmods.h2m -Source5: akmodsposttrans Source6: akmods.service.in Source7: akmods-shutdown Source8: akmods-shutdown.service @@ -115,7 +114,6 @@ mkdir -p %{buildroot}%{_usrsrc}/%{name} \ install -pm 0755 %{SOURCE1} %{buildroot}%{_sbindir}/ install -pm 0755 %{SOURCE2} %{buildroot}%{_sbindir}/ install -pm 0755 %{SOURCE12} %{buildroot}%{_sbindir}/ -install -pm 0755 %{SOURCE5} %{buildroot}%{_sysconfdir}/kernel/postinst.d/ install -pm 0644 %{SOURCE14} %{buildroot}%{_sysconfdir}/logrotate.d/%{name} install -pm 0640 %{SOURCE16} %{buildroot}%{_sysconfdir}/pki/%{name}/ install -pm 0755 %{SOURCE17} %{buildroot}%{_sbindir}/kmodgenca @@ -180,7 +178,6 @@ useradd -r -g akmods -d /var/cache/akmods/ -s /sbin/nologin \ %dir %attr(750,root,akmods) %{_sysconfdir}/pki/%{name}/private %config(noreplace) %attr(640,root,akmods) %{_sysconfdir}/pki/%{name}/cacert.config.in %config(noreplace) %{_sysconfdir}/logrotate.d/%{name} -%{_sysconfdir}/kernel/postinst.d/akmodsposttrans %{_unitdir}/akmods.service %{_unitdir}/akmods@.service %{_sbindir}/akmods-shutdown diff --git a/akmodsposttrans b/akmodsposttrans deleted file mode 100755 index 12b1804..0000000 --- a/akmodsposttrans +++ /dev/null @@ -1,47 +0,0 @@ -#!/bin/bash - -# -# akmodposttrans - Calls akmods for newly installed kernels -# -# Copyright (c) 2009 Thorsten Leemhuis -# Copyright (c) 2017 Nicolas Chauvet -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -# just check in case a user calls this directly -if [[ ! -w /var ]] ; then - echo "Needs to run as root to be able to install rpms." >&2 - exit 4 -fi - -# needs to run in background as rpmdb might be locked otherwise -if [ -e /bin/systemctl ] ; then - # Exit early if system-update.target is active - rhbz#1518401 - /bin/systemctl is-active system-update.target &>/dev/null - RET=$? - - [ $RET == 0 ] && exit 0 - - /bin/systemctl restart akmods@${1}.service --no-block >/dev/null 2>&1 -else - nohup /usr/sbin/akmods --from-kernel-posttrans --kernels ${1} > /dev/null 2>&1 & -fi - -exit 0 From 67b5b8a37e2bcd981e163738bd026465d03ad140 Mon Sep 17 00:00:00 2001 From: Nicolas Chauvet Date: Tue, 1 Oct 2024 21:49:20 +0200 Subject: [PATCH 43/79] Bump akmods version --- akmods | 2 +- akmods-kmodgenca | 2 +- akmods.spec | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/akmods b/akmods index d99a7d6..758fdf9 100644 --- a/akmods +++ b/akmods @@ -37,7 +37,7 @@ # global vars myprog="akmods" -myver="0.5.10" +myver="0.6.0" kmodlogfile= continue_line="" tmpdir= diff --git a/akmods-kmodgenca b/akmods-kmodgenca index e490834..0fc312c 100644 --- a/akmods-kmodgenca +++ b/akmods-kmodgenca @@ -35,7 +35,7 @@ # DECLARE CONSTANTS # Script Information readonly SCRIPT_NAME="kmodgenca" -readonly SCRIPT_VERSION="0.5.7" +readonly SCRIPT_VERSION="0.6.0" # Directories readonly AKMODS_DIR="/etc/pki/akmods" diff --git a/akmods.spec b/akmods.spec index a3d85e1..e3de822 100644 --- a/akmods.spec +++ b/akmods.spec @@ -1,5 +1,5 @@ Name: akmods -Version: 0.5.10 +Version: 0.6.0 Release: %autorelease Summary: Automatic kmods build and install tool From 408074abf6a05fad11260f520e9d0455a28a3245 Mon Sep 17 00:00:00 2001 From: Rohan Barar Date: Wed, 2 Oct 2024 07:30:18 +1000 Subject: [PATCH 44/79] Add check for elevated privileges --- akmods-kmodgenca | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/akmods-kmodgenca b/akmods-kmodgenca index 0fc312c..2c16dc5 100644 --- a/akmods-kmodgenca +++ b/akmods-kmodgenca @@ -28,9 +28,10 @@ # EXIT STATUS CODES AND DESCRIPTIONS # 0 - SUCCESS -# 1 - INVALID COMMAND LINE ARGUMENT -# 2 - BROKEN EXISTING KEY PAIR -# 3 - CA CERTIFICATE CONFIGURATION MODIFICATION FAILED +# 1 - INSUFFICIENT PRIVILEGES +# 2 - INVALID COMMAND LINE ARGUMENT +# 3 - BROKEN EXISTING KEY PAIR +# 4 - CA CERTIFICATE CONFIGURATION MODIFICATION FAILED # DECLARE CONSTANTS # Script Information @@ -84,6 +85,15 @@ function help() { echo "" } +function check_root() { + if [ "$EUID" -ne 0 ]; then + echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} INSUFFICIENT PRIVILEGES!" + echo "Please run the command using 'sudo' or as root." + echo "Quitting." + exit 1 + fi +} + function parse_arguments() { while [ "$1" ] ; do case "$1" in @@ -139,7 +149,7 @@ function parse_arguments() { if [[ "$BAD_ARGS" -eq 1 ]]; then echo "" help >&2 - exit 1 + exit 2 fi # Display script help information if requested. @@ -199,7 +209,7 @@ function check_broken_key_pair() { echo "Quitting." # Exit script. - exit 2 + exit 3 fi } @@ -333,7 +343,7 @@ function create_ca_cert_config() { echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} CACERT CONFIG FILE MODIFICATION FAILED." echo "Failed to update the CA certificate configuration file at '${CACERT_CONFIG_PATH}'." echo "Quitting." - exit 3 + exit 4 fi } @@ -385,6 +395,9 @@ function update_key_symlinks() { } # SCRIPT MAINLINE +# Check for elevated privileges. +check_root + # Parse any supplied arguments. parse_arguments "$@" From 8281cf95b5f2b7b2b133d1743405c3fbfbef9066 Mon Sep 17 00:00:00 2001 From: Rohan Barar Date: Wed, 2 Oct 2024 17:09:12 +1000 Subject: [PATCH 45/79] Improved error handling + Bug fixes --- akmods-kmodgenca | 311 ++++++++++++++++++++++++++++------------------- 1 file changed, 183 insertions(+), 128 deletions(-) diff --git a/akmods-kmodgenca b/akmods-kmodgenca index 2c16dc5..dbb8e03 100644 --- a/akmods-kmodgenca +++ b/akmods-kmodgenca @@ -31,7 +31,16 @@ # 1 - INSUFFICIENT PRIVILEGES # 2 - INVALID COMMAND LINE ARGUMENT # 3 - BROKEN EXISTING KEY PAIR -# 4 - CA CERTIFICATE CONFIGURATION MODIFICATION FAILED +# 4 - MISSING CACERT CONFIGURATION TEMPLATE +# 5 - FAILED TO READ CA CERTIFICATE CONFIGURATION TEMPLATE +# 6 - FAILED TO WRITE CA CERTIFICATE CONFIGURATION FILE +# 7 - UNSUCCESSFUL OPENSSL KEY PAIR CREATION COMMAND +# 8 - FAILED TO CREATE KEY PAIR FILES + +# ENFORCE STRICT ERROR HANDLING +# - Exit script on error. +# - Ensure pipelines fail on the first error. +set -eo pipefail # DECLARE CONSTANTS # Script Information @@ -53,6 +62,7 @@ readonly RESTORECON_PATH="/usr/sbin/restorecon" readonly BOLD_RED_TEXT="\e[1;31m" readonly BOLD_YELLOW_TEXT="\e[1;33m" readonly BOLD_GREEN_TEXT="\033[1;32m" +readonly BOLD_BLUE_TEXT="\e[1;34m" readonly BOLD_GREY_TEXT="\e[1;37m" readonly CLEAR_TEXT="\e[0m" @@ -86,69 +96,75 @@ function help() { } function check_root() { + # Notify user. + echo -e "${BOLD_BLUE_TEXT}INFO:${CLEAR_TEXT} CHECKING FOR ELEVATED PRIVILEGES..." + if [ "$EUID" -ne 0 ]; then - echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} INSUFFICIENT PRIVILEGES!" - echo "Please run the command using 'sudo' or as root." - echo "Quitting." + echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} INSUFFICIENT PRIVILEGES!" >&2 + echo "Please run the command using 'sudo' or as root." >&2 + echo "Quitting." >&2 exit 1 fi } function parse_arguments() { - while [ "$1" ] ; do - case "$1" in - -a|--auto) - AUTOMATIC_BUILD=1 - shift - ;; - -f|--force) - FORCE_BUILD=1 - shift - ;; - -h|--help) - SHOW_HELP=1 - shift - ;; - -V|--version) - SHOW_VER=1 - shift - ;; - -*) - # Handle combined single-letter options. - for (( i=1; i<${#1}; i++ )); do - case "${1:$i:1}" in - a) - AUTOMATIC_BUILD=1 - ;; - f) - FORCE_BUILD=1 - ;; - h) - SHOW_HELP=1 - ;; - V) - SHOW_VER=1 - ;; - *) - echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} INVALID OPTION '${1:$i:1}' in '${1}'." >&2 - BAD_ARGS=1 - ;; - esac - done - shift - ;; - *) - echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} INVALID OPTION '${1}'." >&2 - BAD_ARGS=1 - shift - ;; - esac - done + if [ $# -gt 0 ]; then + while [ "$1" ] ; do + case "$1" in + -a|--auto) + AUTOMATIC_BUILD=1 + shift + ;; + -f|--force) + FORCE_BUILD=1 + shift + ;; + -h|--help) + SHOW_HELP=1 + shift + ;; + -V|--version) + SHOW_VER=1 + shift + ;; + -*) + # Handle combined single-letter options. + for (( i=1; i<${#1}; i++ )); do + case "${1:$i:1}" in + a) + AUTOMATIC_BUILD=1 + ;; + f) + FORCE_BUILD=1 + ;; + h) + SHOW_HELP=1 + ;; + V) + SHOW_VER=1 + ;; + *) + echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} INVALID OPTION '${1:$i:1}' in '${1}'." >&2 + BAD_ARGS=1 + ;; + esac + done + shift + ;; + *) + echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} INVALID OPTION '${1}'." >&2 + BAD_ARGS=1 + shift + ;; + esac + done + fi - # Display help message and then exit in the event of invalid command line argument(s). + # Display help message and then exit in the event of invalid argument(s). if [[ "$BAD_ARGS" -eq 1 ]]; then - echo "" + echo "" >&2 help >&2 + echo "Quitting." >&2 exit 2 fi @@ -159,28 +175,28 @@ function parse_arguments() { # Display script version information if requested. if [[ "$SHOW_VER" -eq 1 ]]; then - "${SCRIPT_NAME} v${SCRIPT_VERSION}" + echo "${SCRIPT_NAME} v${SCRIPT_VERSION}" fi # Exit script if version and/or help information requested. if [ "$SHOW_VER" -eq 1 ] || [ "$SHOW_HELP" -eq 1 ]; then if [ "$AUTOMATIC_BUILD" -eq 1 ]; then - echo -e "${BOLD_YELLOW_TEXT}WARNING:${CLEAR_TEXT} IGNORING '-a' (--auto)." + echo -e "${BOLD_YELLOW_TEXT}WARNING:${CLEAR_TEXT} IGNORING '-a' (--auto)." >&2 fi if [ "$FORCE_BUILD" -eq 1 ]; then - echo -e "${BOLD_YELLOW_TEXT}WARNING:${CLEAR_TEXT} IGNORING '-f' (--force)." + echo -e "${BOLD_YELLOW_TEXT}WARNING:${CLEAR_TEXT} IGNORING '-f' (--force)." >&2 fi exit 0 fi # Warn user regarding forced builds. if [[ "$FORCE_BUILD" -eq 1 ]]; then - echo -e "${BOLD_YELLOW_TEXT}WARNING:${CLEAR_TEXT} FORCED BUILD SELECTED. KEY PAIR OVERWRITE MAY OCCUR!" + echo -e "${BOLD_YELLOW_TEXT}WARNING:${CLEAR_TEXT} FORCED BUILD SELECTED. KEY PAIR OVERWRITE MAY OCCUR!" >&2 fi # Warn user regarding automatic builds. if [[ "$AUTOMATIC_BUILD" -eq 1 ]]; then - echo -e "${BOLD_YELLOW_TEXT}WARNING:${CLEAR_TEXT} AUTOMATIC BUILD SELECTED. USING DEFAULT VALUES FOR CA/KEY PAIR CREATION." + echo -e "${BOLD_YELLOW_TEXT}WARNING:${CLEAR_TEXT} AUTOMATIC BUILD SELECTED. USING DEFAULT VALUES FOR CA/KEY PAIR CREATION." >&2 fi } @@ -200,13 +216,13 @@ function check_broken_key_pair() { if [[ "$pub_key_exists" -ne "$pri_key_exists" && "$FORCE_BUILD" -eq 0 ]]; then # Notify user. - echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} BROKEN EXISTING KEY PAIR." - echo "Both a public key and a private key must exist." + echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} BROKEN EXISTING KEY PAIR." >&2 + echo "Both a public key and a private key must exist." >&2 # Dynamic status output with colours. - echo -e " ${PUBLIC_KEY_PATH}: $( [[ $pub_key_exists -eq 1 ]] && echo -e "${BOLD_GREEN_TEXT}PRESENT${CLEAR_TEXT}" || echo -e "${BOLD_RED_TEXT}MISSING${CLEAR_TEXT}" )" - echo -e " ${PRIVATE_KEY_PATH}: $( [[ $pri_key_exists -eq 1 ]] && echo -e "${BOLD_GREEN_TEXT}PRESENT${CLEAR_TEXT}" || echo -e "${BOLD_RED_TEXT}MISSING${CLEAR_TEXT}" )" - echo "Quitting." + echo -e " ${PUBLIC_KEY_PATH}: $( [[ $pub_key_exists -eq 1 ]] && echo -e "${BOLD_GREEN_TEXT}PRESENT${CLEAR_TEXT}" || echo -e "${BOLD_RED_TEXT}MISSING${CLEAR_TEXT}" )" >&2 + echo -e " ${PRIVATE_KEY_PATH}: $( [[ $pri_key_exists -eq 1 ]] && echo -e "${BOLD_GREEN_TEXT}PRESENT${CLEAR_TEXT}" || echo -e "${BOLD_RED_TEXT}MISSING${CLEAR_TEXT}" )" >&2 + echo "Quitting." >&2 # Exit script. exit 3 @@ -214,6 +230,9 @@ function check_broken_key_pair() { } function check_existing_key_pair() { + # Notify user. + echo -e "${BOLD_BLUE_TEXT}INFO:${CLEAR_TEXT} CHECKING FOR AN EXISTING KEY PAIR..." + # Terminate the script when: # 1. Both a certificate (public key) and private key already exist, AND # 2. A forced rebuild was not requested (i.e., 'FORCE_BUILD' is NOT '1') @@ -225,39 +244,41 @@ function check_existing_key_pair() { [ "$FORCE_BUILD" -eq 0 ]; then # Notify user. - echo -e "${BOLD_YELLOW_TEXT}WARNING:${CLEAR_TEXT} EXISTING KEY PAIR." - echo "Please specify argument '--force' to overwrite the existing key pair." - echo "Quitting." + echo -e "${BOLD_YELLOW_TEXT}WARNING:${CLEAR_TEXT} EXISTING KEY PAIR." >&2 + echo "Please specify argument '--force' to overwrite the existing key pair." >&2 + echo "Quitting." >&2 # Exit script. exit 0 fi } -function request_key_pair_name() { +function set_key_pair_name() { if [ "$AUTOMATIC_BUILD" -eq 0 ]; then while true; do local key_pair_file_name="" local valid_name=1 + # Request key pair name from user. + # shellcheck disable=SC2162 read -p "Key Pair Name: " key_pair_file_name # Check for empty string. if [[ -z $(echo "$key_pair_file_name" | xargs) ]]; then valid_name=0 - echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} NAME MUST NOT BE EMPTY.\n" + echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} NAME MUST NOT BE EMPTY.\n" >&2 fi # Ensure name is not '.' or '..'. if [[ $(echo "$key_pair_file_name" | xargs) == "." ]] || [[ $(echo "$key_pair_file_name" | xargs) == ".." ]]; then valid_name=0 - echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} NAME MUST NOT BE '.' OR '..'.\n" + echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} NAME MUST NOT BE '.' OR '..'.\n" >&2 fi # Ensure name is not longer than 255 characters. - if [ $(echo "$key_pair_file_name" | xargs | awk '{print length}') -gt 255 ]; then + if [ "$(echo "$key_pair_file_name" | xargs | awk '{print length}')" -gt 255 ]; then valid_name=0 - echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} NAME MUST NOT BE LONGER THAN 255 CHARACTERS.\n" + echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} NAME MUST NOT BE LONGER THAN 255 CHARACTERS.\n" >&2 fi # Ensure name only contains valid characters. @@ -273,20 +294,21 @@ function request_key_pair_name() { valid_name=0 # Inform user of illegal characters within provided name. - local illegal_chars=$(echo "$key_pair_file_name" | awk -F '' '{for(i=1;i<=NF;i++) if ($i !~ /^[0-9a-zA-Z._-]$/) print $i}' | sort -u | tr -d '\n') - echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} NAME MUST NOT CONTAIN ILLEGAL CHARACTERS." - echo -e "Illegal characters in provided name:" + local illegal_chars + illegal_chars=$(echo "$key_pair_file_name" | awk -F '' '{for(i=1;i<=NF;i++) if ($i !~ /^[0-9a-zA-Z._-]$/) print $i}' | sort -u | tr -d '\n') + echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} NAME MUST NOT CONTAIN ILLEGAL CHARACTERS." >&2 + echo -e "Illegal characters in provided name:" >&2 for (( i=0; i<${#illegal_chars}; i++ )); do - echo "- '${illegal_chars:i:1}'" + echo "- '${illegal_chars:i:1}'" >&2 done - echo -e "\nPlease ensure the name only contains letters, numbers, periods, underscores and hyphens.\n" + echo -e "\nPlease ensure the name only contains letters, numbers, periods, underscores and hyphens.\n" >&2 fi fi # Ensure key pair with same name does not exist. if [ -f "${PUBLIC_KEY_DIR}/${key_pair_file_name}.der" ] || [ -f "${PRIVATE_KEY_DIR}/${key_pair_file_name}.priv" ]; then valid_name=0 - echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} EXISTING KEY PAIR WITH SAME NAME.\n" + echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} EXISTING KEY PAIR WITH SAME NAME.\n" >&2 fi # Break the loop if a valid name was provided. @@ -297,58 +319,72 @@ function request_key_pair_name() { # Update global key pair name variable. KEYNAME="$key_pair_file_name" + else + # Handle the extremely unlikely occurrence of a key pair name conflict with an existing key pair. + while [ -f "${PUBLIC_KEY_DIR}/${KEYNAME}.der" ]; do + KEYNAME="$(hostname)_$(date +%s)_$(uuidgen | tr -d '-')" + done fi } -function create_ca_cert_config() { - echo "UPDATING '${CACERT_CONFIG_PATH}'..." +function create_cacert_config() { + # Notify user. + echo -e "${BOLD_BLUE_TEXT}INFO:${CLEAR_TEXT} UPDATING CACERT CONFIGURATION FILE AT '${CACERT_CONFIG_PATH}'..." - # Handle the extremely unlikely occurrence of a key pair name conflict with an existing key pair. - while [ -f "${PUBLIC_KEY_DIR}/${KEYNAME}.der" ]; do - KEYNAME="$(hostname)_$(date +%s)_$(uuidgen | tr -d '-')" - done - - if [ "$AUTOMATIC_BUILD" -eq 1 ]; then - # Set '-batch' argument. - AUTOMATIC_BUILD_OPTION="-batch" - - # Initialise output variable. + # Check if the cacert configuration template exists. + if [[ -f "${CACERT_CONFIG_PATH}.in" ]]; then local sed_output="" + local sed_exit_status=0 - # Utilise default values if 'AUTOMATIC_BUILD' is equal to '1'. - # Set OpenSSL field values. - # Comment default and min/max values. - # Note: Requires superuser permissions (i.e. sudo). - sed_output=$(sed -e "s#\(0.organizationName *= \).*#\1$(hostname)#" \ - -e "s#\(organizationalUnitName *= \).*#\1$(hostname)#" \ - -e "s#\(emailAddress *= \).*#\1akmods@$(hostname)#" \ - -e "s#\(localityName *= \).*#\1None#" \ - -e "s#\(stateOrProvinceName *= \).*#\1None#" \ - -e "s#\(countryName *= \).*#\1$(locale country_ab2)#" \ - -e "s#\(commonName *= \).*#\1${KEYNAME}#" \ - -e "s/^[^#]*_default *= /#&/" \ - -e "s/^[^#]*_min/#&/" \ - -e "s/^[^#]*_max/#&/" "${CACERT_CONFIG_PATH}.in" 2>&1 | tee "$CACERT_CONFIG_PATH" > /dev/null) + if [ "$AUTOMATIC_BUILD" -eq 1 ]; then + # Set '-batch' argument. + AUTOMATIC_BUILD_OPTION="-batch" + + # Utilise default values if 'AUTOMATIC_BUILD' is equal to '1'. + # - Set OpenSSL field values. + # - Comment default and min/max values. + sed_output=$(sed -e "s#\(0.organizationName *= \).*#\1$(hostname)#" \ + -e "s#\(organizationalUnitName *= \).*#\1$(hostname)#" \ + -e "s#\(emailAddress *= \).*#\1akmods@$(hostname)#" \ + -e "s#\(localityName *= \).*#\1None#" \ + -e "s#\(stateOrProvinceName *= \).*#\1None#" \ + -e "s#\(countryName *= \).*#\1$(locale country_ab2)#" \ + -e "s#\(commonName *= \).*#\1${KEYNAME}#" \ + -e "s/^[^#]*_default *= /#&/" \ + -e "s/^[^#]*_min/#&/" \ + -e "s/^[^#]*_max/#&/" "${CACERT_CONFIG_PATH}.in") + sed_exit_status=$? + else + # Request user enter values manually if 'AUTOMATIC_BUILD' is equal to '0'. + # Request OpenSSL prompt user for values later. + sed_output=$(sed -e "s#\(prompt *= \).*#\1yes#" "${CACERT_CONFIG_PATH}.in") + sed_exit_status=$? + fi + + # Check if 'sed' command failed. + if [ "$sed_exit_status" -ne 0 ]; then + echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} FAILED TO READ CACERT CONFIGURATION TEMPLATE at '${CACERT_CONFIG_PATH}.in'." >&2 + echo "Quitting." >&2 + exit 5 + else + # Note: Requires superuser permissions (i.e. sudo). + if ! echo "$sed_output" > "$CACERT_CONFIG_PATH"; then + echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} FAILED TO WRITE CACERT CONFIGURATION FILE to '${CACERT_CONFIG_PATH}'." >&2 + echo "Quitting." >&2 + exit 6 + fi + fi else - # Request user enter values manually if 'AUTOMATIC_BUILD' is equal to '0'. - # Request OpenSSL prompt user for values later. - # Note: Requires superuser permissions (i.e. sudo). - sed_output=$(sed -e "s#\(prompt *= \).*#\1yes#" "${CACERT_CONFIG_PATH}.in" | tee "$CACERT_CONFIG_PATH" > /dev/null) - fi - - # Check if 'sed' command failed. - # shellcheck disable=SC2181 - if [ "$?" -ne 0 ]; then - echo "$sed_output" - echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} CACERT CONFIG FILE MODIFICATION FAILED." - echo "Failed to update the CA certificate configuration file at '${CACERT_CONFIG_PATH}'." - echo "Quitting." + echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} MISSING CACERT CONFIGURATION TEMPLATE!" >&2 + echo "Failed to locate the CAcert configuration template at '${CACERT_CONFIG_PATH}.in'." >&2 + echo "Quitting." >&2 exit 4 fi } function create_new_key_pair() { - echo "CREATING NEW KEY PAIR..." + # Notify user. + echo -e "${BOLD_BLUE_TEXT}INFO:${CLEAR_TEXT} CREATING NEW KEY PAIR..." # Prepare an OpenSSL command to generate the key pair. local key_pair_generation_command=( @@ -369,10 +405,26 @@ function create_new_key_pair() { # Execute the key pair generation command within the 'akmods' group context. # Ensure 'rw-rwx---' permissions. # Note: Requires superuser permissions (i.e. sudo). - sg akmods -c "umask 037 && ${key_pair_generation_command[*]}" + if sg akmods -c "umask 037 && ${key_pair_generation_command[*]}"; then + # Check if both a public and a private key file were created. + if [[ ! -f "${PUBLIC_KEY_DIR}/${KEYNAME}.der" || ! -f "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" ]]; then + echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} KEY PAIR CREATION FAILED!" >&2 + echo "The OpenSSL key pair generation command ran, but key files were not created." >&2 + echo "Quitting." >&2 + exit 8 + fi + else + echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} KEY PAIR CREATION FAILED!" >&2 + echo "The OpenSSL key pair generation command did not complete successfully." >&2 + echo "Quitting." >&2 + exit 7 + fi } function set_key_permissions() { + # Notify user. + echo -e "${BOLD_BLUE_TEXT}INFO:${CLEAR_TEXT} SETTING KEY PAIR PERMISSIONS..." + # Ensure that akmods group can read keys. # Note: Requires superuser permissions (i.e. sudo). chmod g+r "${PUBLIC_KEY_DIR}/${KEYNAME}.der" @@ -387,6 +439,9 @@ function set_key_permissions() { } function update_key_symlinks() { + # Notify user. + echo -e "${BOLD_BLUE_TEXT}INFO:${CLEAR_TEXT} UPDATING KEY PAIR SYMLINKS..." + # Note: Requires superuser permissions (i.e. sudo). ln -nsf "${PUBLIC_KEY_DIR}/${KEYNAME}.der" "$PUBLIC_KEY_PATH" ln -nsf "${PRIVATE_KEY_DIR}/${KEYNAME}.priv" "$PRIVATE_KEY_PATH" @@ -395,23 +450,23 @@ function update_key_symlinks() { } # SCRIPT MAINLINE -# Check for elevated privileges. -check_root - # Parse any supplied arguments. parse_arguments "$@" +# Check for elevated privileges. +check_root + # Check for broken key pairs. check_broken_key_pair # Check for existing key pair. check_existing_key_pair -# Request user for key pair name. -request_key_pair_name +# Set key pair name. +set_key_pair_name # Create 'cacert.config' using template file 'cacert.config.in'. -create_ca_cert_config +create_cacert_config # Create new key pair. create_new_key_pair @@ -427,8 +482,8 @@ echo -e "\n${BOLD_GREEN_TEXT}SUCCESS!${CLEAR_TEXT}" echo "Public Key (Certificate) created at: ${PUBLIC_KEY_DIR}/${KEYNAME}.der" echo "Private Key created at: ${PRIVATE_KEY_DIR}/${KEYNAME}.priv" echo -e "\nSymlinks:" -echo "${KEYNAME}.der --> ${PUBLIC_KEY_PATH}" -echo "${KEYNAME}.priv --> ${PRIVATE_KEY_PATH}" +echo "${KEYNAME}.der -> ${PUBLIC_KEY_PATH}" +echo "${KEYNAME}.priv -> ${PRIVATE_KEY_PATH}" # Exit script. exit 0 From 3c1ccb23465554ace77d06d82607e276fc01c921 Mon Sep 17 00:00:00 2001 From: Rohan Barar Date: Wed, 2 Oct 2024 22:31:46 +1000 Subject: [PATCH 46/79] Add robust missing key pair logic --- akmods-kmodgenca | 104 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 98 insertions(+), 6 deletions(-) diff --git a/akmods-kmodgenca b/akmods-kmodgenca index dbb8e03..7b98e29 100644 --- a/akmods-kmodgenca +++ b/akmods-kmodgenca @@ -30,7 +30,7 @@ # 0 - SUCCESS # 1 - INSUFFICIENT PRIVILEGES # 2 - INVALID COMMAND LINE ARGUMENT -# 3 - BROKEN EXISTING KEY PAIR +# 3 - BROKEN SYMLINKS TO DEFAULT KEY PAIR # 4 - MISSING CACERT CONFIGURATION TEMPLATE # 5 - FAILED TO READ CA CERTIFICATE CONFIGURATION TEMPLATE # 6 - FAILED TO WRITE CA CERTIFICATE CONFIGURATION FILE @@ -201,11 +201,101 @@ function parse_arguments() { } function check_broken_key_pair() { + # Check for broken non-selected key pairs. + local unmatched_public_key_paths=() + local unmatched_private_key_paths=() + + # Store paths of public and private keys. + local public_key_paths=() + local private_key_paths=() + # Note: Requires superuser permissions (i.e., sudo). + mapfile -t public_key_paths < <(find "$PUBLIC_KEY_DIR" -maxdepth 1 -name "*.der") + mapfile -t private_key_paths < <(find "$PRIVATE_KEY_DIR" -maxdepth 1 -name "*.priv") + + # Find public/private keys without corresponding private/public keys. + local key_file_path + for key_file_path in "${public_key_paths[@]}"; do + # Skip symlink. + if [[ "$key_file_path" == "$PUBLIC_KEY_PATH" ]]; then + continue + fi + + # Remove file extension. + local public_key_name + public_key_name="$(basename "$key_file_path")" + public_key_name="${public_key_name%.*}" + + # Check if the corresponding private key exists. + local found=0 + for private_key_path in "${private_key_paths[@]}"; do + if [[ "$private_key_path" == "${PRIVATE_KEY_DIR}/${public_key_name}.priv" ]]; then + found=1 + break + fi + done + + # Store public key file name (with extension) if unpaired. + if [[ "$found" -eq 0 ]]; then + unmatched_public_key_paths+=("$key_file_path") + fi + done + + for key_file_path in "${private_key_paths[@]}"; do + # Skip symlink. + if [[ "$key_file_path" == "$PRIVATE_KEY_PATH" ]]; then + continue + fi + + # Remove file extension. + local private_key_name + private_key_name="$(basename "$key_file_path")" + private_key_name="${private_key_name%.*}" + + # Check if the corresponding public key exists. + local found=0 + for public_key_path in "${public_key_paths[@]}"; do + if [[ "$public_key_path" == "${PUBLIC_KEY_DIR}/${private_key_name}.der" ]]; then + found=1 + break + fi + done + + # Store private key file name (with extension) if unpaired. + if [[ "$found" -eq 0 ]]; then + unmatched_private_key_paths+=("$key_file_path") + fi + done + + # Check if isolated keys were detected. + if [[ ${#unmatched_private_key_paths[@]} -gt 0 || ${#unmatched_public_key_paths[@]} -gt 0 ]]; then + echo -e "${BOLD_YELLOW_TEXT}WARNING:${CLEAR_TEXT} SOME KEY PAIRS ARE BROKEN!" >&2 + + # Notify user regarding isolated public keys. + if [[ ${#unmatched_public_key_paths[@]} -gt 0 ]]; then + echo "Isolated Public Keys:" >&2 + local isolated_pub_key_path + for isolated_pub_key_path in "${unmatched_public_key_paths[@]}"; do + echo " ${isolated_pub_key_path}" >&2 + done + echo "" >&2 + fi + + # Notify user regarding isolated private keys. + if [[ ${#unmatched_private_key_paths[@]} -gt 0 ]]; then + echo "Isolated Private Keys:" >&2 + local isolated_pri_key_path + for isolated_pri_key_path in "${unmatched_private_key_paths[@]}"; do + echo " ${isolated_pri_key_path}" >&2 + done + echo "" >&2 + fi + fi + # Terminate the script when: # 1. A certificate (public key) OR private key exists (but not both), AND # 2. A forced rebuild was not requested (i.e., 'FORCE_BUILD' is NOT '1') - # Note: This approach will also detect broken symlinks (i.e., return 0). + # Check for broken symlinks to the currently selected pair of keys. # Note: Requires superuser permissions (i.e. sudo). # shellcheck disable=SC2155 local pub_key_exists=$(readlink -e "$PUBLIC_KEY_PATH" &>/dev/null && echo 1 || echo 0) @@ -216,12 +306,14 @@ function check_broken_key_pair() { if [[ "$pub_key_exists" -ne "$pri_key_exists" && "$FORCE_BUILD" -eq 0 ]]; then # Notify user. - echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} BROKEN EXISTING KEY PAIR." >&2 - echo "Both a public key and a private key must exist." >&2 + echo -e "${BOLD_RED_TEXT}ERROR:${CLEAR_TEXT} BROKEN SYMLINK(S) TO THE DEFAULT KEY PAIR!" >&2 + echo "Valid symlinks to a public and private key must exist." >&2 + echo "" >&2 # Dynamic status output with colours. - echo -e " ${PUBLIC_KEY_PATH}: $( [[ $pub_key_exists -eq 1 ]] && echo -e "${BOLD_GREEN_TEXT}PRESENT${CLEAR_TEXT}" || echo -e "${BOLD_RED_TEXT}MISSING${CLEAR_TEXT}" )" >&2 - echo -e " ${PRIVATE_KEY_PATH}: $( [[ $pri_key_exists -eq 1 ]] && echo -e "${BOLD_GREEN_TEXT}PRESENT${CLEAR_TEXT}" || echo -e "${BOLD_RED_TEXT}MISSING${CLEAR_TEXT}" )" >&2 + echo -e "${PUBLIC_KEY_PATH}: $( [[ $pub_key_exists -eq 1 ]] && echo -e "${BOLD_GREEN_TEXT}WORKING${CLEAR_TEXT}" || echo -e "${BOLD_RED_TEXT}BROKEN${CLEAR_TEXT}" )" >&2 + echo -e "${PRIVATE_KEY_PATH}: $( [[ $pri_key_exists -eq 1 ]] && echo -e "${BOLD_GREEN_TEXT}WORKING${CLEAR_TEXT}" || echo -e "${BOLD_RED_TEXT}BROKEN${CLEAR_TEXT}" )" >&2 + echo "" >&2 echo "Quitting." >&2 # Exit script. From 0a48edaa3b44bcec30cd5237e95bec8ea320f4a6 Mon Sep 17 00:00:00 2001 From: Nicolas Chauvet Date: Fri, 8 Nov 2024 23:02:08 +0100 Subject: [PATCH 47/79] Fix KEYNAME lengh - rhbz#2323702 --- akmods-kmodgenca | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/akmods-kmodgenca b/akmods-kmodgenca index 7b98e29..8cd99f7 100644 --- a/akmods-kmodgenca +++ b/akmods-kmodgenca @@ -75,7 +75,8 @@ SHOW_VER=0 BAD_ARGS=0 # Unique New Key Pair Name (Hostname + UNIX/POSIX Timestamp + Dashless UUID) -KEYNAME="$(hostname)_$(date +%s)_$(uuidgen | tr -d '-')" +cert_hostname="$(hostname)" +KEYNAME="${cert_hostname:0:44}_$(date +%s)_$(uuidgen | awk -F '-' '{print $1}')" # Other AUTOMATIC_BUILD_OPTION="" @@ -414,7 +415,7 @@ function set_key_pair_name() { else # Handle the extremely unlikely occurrence of a key pair name conflict with an existing key pair. while [ -f "${PUBLIC_KEY_DIR}/${KEYNAME}.der" ]; do - KEYNAME="$(hostname)_$(date +%s)_$(uuidgen | tr -d '-')" + KEYNAME="${cert_hostname:0:44}_$(date +%s)_$(uuidgen | awk -F '-' '{print $1}')" done fi } From ebab5b25130e37d7bcb6f3fac6f92b59281e1089 Mon Sep 17 00:00:00 2001 From: Nicolas Chauvet Date: Thu, 28 Nov 2024 09:21:15 +0100 Subject: [PATCH 48/79] Validate or discard default_kernel - rhbz#2270414 --- akmods | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/akmods b/akmods index 758fdf9..b0ed55f 100644 --- a/akmods +++ b/akmods @@ -261,6 +261,10 @@ check_default_kernel() # Leave jq as optional - isDefault requires systemd 253 if command -v jq >/dev/null ; then default_kernel="$(bootctl list --json=short | jq -r '.[] | select(.isDefault).version')" + # Validate the result or discard - rhbz#2270414 + if [[ ! -f /boot/vmlinuz-"${default_kernel}" ]] ; then + default_kernel="" + fi fi else # They use neither systemd-boot nor grub2 echo -n "Unable to figure out the default kernel" >&2 From b8a8b20588e4cff6c5ca64034ddf7d8ee103c7aa Mon Sep 17 00:00:00 2001 From: Marcel Hetzendorfer Date: Wed, 10 Apr 2024 09:57:11 +0200 Subject: [PATCH 49/79] Show building and installing on plymouth boot screen --- akmods | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/akmods b/akmods index 758fdf9..a5787b4 100644 --- a/akmods +++ b/akmods @@ -47,6 +47,39 @@ verboselevel=2 # So we always retry anyway alwaystry=1 +# Check Running plymouth +no_plymouth=1 +last_message="" + +function check_plymouth() { + which plymouth > /dev/null 2> /dev/null + if [[ $? -eq 1 ]] + then + no_plymouth=1 + return 0 + fi + + plymouth --ping + no_plymouth=$? +} + +# new or del, msg +akmods_echo_plymouth(){ + if [[ $no_plymouth -eq 0 ]] + then + if [[ $1 -eq 1 ]] + then + plymouth display-message --text="$2" + last_message=$2 + else + if [ -z "${last_message}" ]; then + plymouth hide-message --text="$last_message" & + last_message="" + fi + fi + fi +} + akmods_echo() { # where to output @@ -327,6 +360,7 @@ buildinstall_kmod() unset TMPDIR # build module using akmod + akmods_echo_plymouth 1 "akmod: Building ${this_kmodsrpm}..." akmods_echo 1 4 "Building RPM using the command '/usr/sbin/akmodsbuild --kernels ${this_kernelver} ${this_kmodsrpm}'" /sbin/runuser -s /bin/bash -c "/usr/sbin/akmodsbuild --quiet --kernels ${this_kernelver} --outputdir ${tmpdir}results --logfile ${tmpdir}/akmodsbuild.log ${this_kmodsrpm}" akmods >> "${kmodlogfile}" 2>&1 local returncode=$? @@ -341,6 +375,10 @@ buildinstall_kmod() if [[ -n "${continue_line}" ]] ; then akmods_echo 1 2 --failure fi + + akmods_echo_plymouth 0 "" + akmods_echo_plymouth 1 "akmod: Building ${this_kmodsrpm} failed!" + sleep 5 akmods_echo 2 1 "Building rpms failed; see /var/cache/akmods/${this_kmodname}/${this_kmodverrel}-for-${this_kernelver}.failed.log for details" cp -fl "${kmodlogfile}" "/var/cache/akmods/${this_kmodname}/${this_kmodverrel}-for-${this_kernelver}.failed.log" kmodlogfile="" @@ -349,6 +387,9 @@ buildinstall_kmod() fi # dnf/yum install - repository disabled on purpose see rfbz#3350 + + akmods_echo_plymouth 0 "" + akmods_echo_plymouth 1 "akmod: Installing ${this_kmodsrpm}..." akmods_echo 1 4 "Installing newly built rpms" if [[ -f /usr/bin/dnf ]] ; then akmods_echo 1 4 "DNF detected" @@ -367,6 +408,10 @@ buildinstall_kmod() if [[ -n "${continue_line}" ]] ; then akmods_echo 1 2 --failure fi + + akmods_echo_plymouth 0 "" + akmods_echo_plymouth 1 "akmod: Installing ${this_kmodsrpm} failed!" + sleep 5 akmods_echo 2 1 "Could not install newly built RPMs. You can find them and the logfile in:" akmods_echo 2 1 "/var/cache/akmods/${this_kmodname}/${this_kmodverrel}-for-${this_kernelver}.failed.log" cp -fl "${kmodlogfile}" "/var/cache/akmods/${this_kmodname}/${this_kmodverrel}-for-${this_kernelver}.failed.log" @@ -381,6 +426,8 @@ buildinstall_kmod() kmodlogfile="" remove_tmpdir + akmods_echo_plymouth 0 "" + return 0 } @@ -625,6 +672,7 @@ while [ "${1}" ] ; do esac done +check_plymouth # sanity checks init From c16ceb525ba715eb80b561abc854e9d33af82e10 Mon Sep 17 00:00:00 2001 From: Nicolas Chauvet Date: Tue, 10 Dec 2024 17:11:45 +0100 Subject: [PATCH 50/79] Drop hostname deps - rhbz#2330137 --- akmods-kmodgenca | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/akmods-kmodgenca b/akmods-kmodgenca index 8cd99f7..8b0c101 100644 --- a/akmods-kmodgenca +++ b/akmods-kmodgenca @@ -75,7 +75,7 @@ SHOW_VER=0 BAD_ARGS=0 # Unique New Key Pair Name (Hostname + UNIX/POSIX Timestamp + Dashless UUID) -cert_hostname="$(hostname)" +cert_hostname="${HOSTNAME}" KEYNAME="${cert_hostname:0:44}_$(date +%s)_$(uuidgen | awk -F '-' '{print $1}')" # Other From f3c0177ccdcbf554108cd405eb9b8db30334bcb5 Mon Sep 17 00:00:00 2001 From: Nicolas Chauvet Date: Wed, 11 Dec 2024 10:09:05 +0100 Subject: [PATCH 51/79] Update others hostname occurences --- akmods-kmodgenca | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/akmods-kmodgenca b/akmods-kmodgenca index 8b0c101..dafe69b 100644 --- a/akmods-kmodgenca +++ b/akmods-kmodgenca @@ -436,9 +436,9 @@ function create_cacert_config() { # Utilise default values if 'AUTOMATIC_BUILD' is equal to '1'. # - Set OpenSSL field values. # - Comment default and min/max values. - sed_output=$(sed -e "s#\(0.organizationName *= \).*#\1$(hostname)#" \ - -e "s#\(organizationalUnitName *= \).*#\1$(hostname)#" \ - -e "s#\(emailAddress *= \).*#\1akmods@$(hostname)#" \ + sed_output=$(sed -e "s#\(0.organizationName *= \).*#\1${cert_hostname}#" \ + -e "s#\(organizationalUnitName *= \).*#\1${cert_hostname}#" \ + -e "s#\(emailAddress *= \).*#\1akmods@${cert_hostname}#" \ -e "s#\(localityName *= \).*#\1None#" \ -e "s#\(stateOrProvinceName *= \).*#\1None#" \ -e "s#\(countryName *= \).*#\1$(locale country_ab2)#" \ From 917aa4c5507043de97d3fcd28d43a852c5538833 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 16 Jan 2025 10:46:20 +0000 Subject: [PATCH 52/79] Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild From e4a63b2938ebb529b56d9be3a2f24df21a3d1412 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 11 Feb 2025 14:36:17 +0100 Subject: [PATCH 53/79] Add sysusers.d config file to allow rpm to create users/groups automatically See https://fedoraproject.org/wiki/Changes/RPMSuportForSystemdSysusers. --- akmods.spec | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/akmods.spec b/akmods.spec index e3de822..6ed6a9a 100644 --- a/akmods.spec +++ b/akmods.spec @@ -68,7 +68,6 @@ Suggests: (kernel-devel if kernel-core) Suggests: (kernel-rt-devel if kernel-rt) # we create a special user that used by akmods to build kmod packages -Requires(pre): shadow-utils # systemd unit requirements. BuildRequires: systemd @@ -94,6 +93,11 @@ after they were installed. %setup -q -c -T cp -p %{SOURCE9} %{SOURCE10} %{SOURCE15} . +# Create a sysusers.d config file +cat >akmods.sysusers.conf </dev/null || groupadd -r akmods -getent passwd akmods >/dev/null || \ -useradd -r -g akmods -d /var/cache/akmods/ -s /sbin/nologin \ - -c "User is used by akmods to build akmod packages" akmods %post %systemd_post akmods.service @@ -197,6 +197,7 @@ useradd -r -g akmods -d /var/cache/akmods/ -s /sbin/nologin \ %dir %attr(-,akmods,akmods) %{_localstatedir}/cache/akmods %dir %attr(0775,root,akmods) %{_localstatedir}/log/%{name} %{_mandir}/man1/* +%{_sysusersdir}/akmods.conf %changelog From b33fbe9087a7fadee214814e43fa9b8e9251eb32 Mon Sep 17 00:00:00 2001 From: Leigh Scott Date: Sat, 3 May 2025 20:07:50 +0100 Subject: [PATCH 54/79] Fix changelog --- changelog | 376 ++++++++++++++++++++++++------------------------------ 1 file changed, 169 insertions(+), 207 deletions(-) diff --git a/changelog b/changelog index 5a64c5b..6bcb2f2 100644 --- a/changelog +++ b/changelog @@ -1,216 +1,178 @@ +* Fri May 02 2025 Marcel Hetzendorfer - 0.6.0-11 +- Show building and installing on plymouth boot screen + +* Tue Feb 11 2025 Zbigniew Jędrzejewski-Szmek - 0.6.0-10 +- Add sysusers.d config file to allow rpm to create users/groups + automatically + +* Thu Jan 16 2025 Fedora Release Engineering - 0.6.0-9 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild + +* Wed Dec 11 2024 Nicolas Chauvet - 0.6.0-8 +- Update others hostname occurences + +* Tue Dec 10 2024 Nicolas Chauvet - 0.6.0-7 +- Drop hostname deps - rhbz#2330137 + +* Thu Nov 28 2024 Nicolas Chauvet - 0.6.0-6 +- Validate or discard default_kernel - rhbz#2270414 + +* Fri Nov 08 2024 Nicolas Chauvet - 0.6.0-5 +- Fix KEYNAME lengh - rhbz#2323702 + +* Wed Oct 02 2024 Rohan Barar - 0.6.0-4 +- Add robust missing key pair logic + +* Wed Oct 02 2024 Rohan Barar - 0.6.0-3 +- Improved error handling + Bug fixes + +* Tue Oct 01 2024 Rohan Barar - 0.6.0-2 +- Add check for elevated privileges + +* Tue Oct 01 2024 Nicolas Chauvet - 0.6.0-1 +- Bump akmods version + +* Tue Oct 01 2024 Nicolas Chauvet - 0.5.10-30 +- Remove duplicate akmodsposttrans call - rhbz#2011120 + +* Thu Sep 26 2024 Rohan Barar - 0.5.10-29 +- Avoid double error on empty user-provided key pair name. + +* Thu Sep 26 2024 Rohan Barar - 0.5.10-28 +- Corrected erroneous code introduced in previous commits. + +* Thu Sep 26 2024 Rohan Barar - 0.5.10-27 +- Fixed typo 'if' to 'fi'. + +* Thu Sep 26 2024 Rohan Barar - 0.5.10-26 +- Added check for existing key pair with same name as user-specified new + key pair name. + +* Thu Sep 26 2024 Rohan Barar - 0.5.10-25 +- Added ability for user to name key pair. + +* Sun Sep 22 2024 Rohan Barar - 0.5.10-24 +- Introduced loop to gracefully handle extremely rare key pair name + collision events. + +* Sat Sep 21 2024 Rohan Barar - 0.5.10-23 +- Refactor key pair naming scheme to enhance robustness + Removed collision + check and key pair backup function due to bug with ':' in file names + alongside superfluous nature of function given improved naming scheme. + +* Sat Sep 21 2024 Rohan Barar - 0.5.10-22 +- Removed 'sudo' prefixes as per request in PR #23. + +* Sat Sep 21 2024 Rohan Barar - 0.5.10-21 +- Further improvements to argument parsing logic. + +* Fri Sep 20 2024 Rohan Barar - 0.5.10-20 +- Improved clarity of exit status code comments. + +* Fri Sep 20 2024 Rohan Barar - 0.5.10-19 +- Revert "Utilise robust shebang." as per request on PR #23. + +* Fri Sep 20 2024 Rohan Barar - 0.5.10-18 +- Added support for combined single-letter arguments + Chowned symlinks. + +* Fri Sep 20 2024 Rohan Barar - 0.5.10-17 +- Improved mokutil error handling + Added sudo prefixes. + +* Fri Sep 20 2024 Rohan Barar - 0.5.10-16 +- Added error handling for failed cacert modification. + +* Fri Sep 20 2024 Rohan Barar - 0.5.10-15 +- Whitespace changes for consistency. + +* Fri Sep 20 2024 Rohan Barar - 0.5.10-14 +- Extract functions to enhance readability + Set 'commonName' to match + 'KEYNAME'. + +* Fri Sep 20 2024 Rohan Barar - 0.5.10-13 +- Added logic to detect broken existing key pairs. + +* Fri Sep 20 2024 Rohan Barar - 0.5.10-12 +- Improved user feedback in event of existing key pair. + +* Fri Sep 20 2024 Rohan Barar - 0.5.10-11 +- Updated copyright information. + +* Fri Sep 20 2024 Rohan Barar - 0.5.10-10 +- Various changes to avoid ShellCheck warnings. + +* Fri Sep 20 2024 Rohan Barar - 0.5.10-9 +- Align license to 80 character width. + +* Fri Sep 20 2024 Rohan Barar - 0.5.10-8 +- Utilise robust shebang. + +* Fri Sep 20 2024 Rohan Barar - 0.5.10-7 +- Removed hard-coded paths. + +* Fri Aug 23 2024 Nicolas Chauvet - 0.5.10-6 +- Fix parsing multiple kernel + +* Fri Aug 23 2024 Nicolas Chauvet - 0.5.10-5 +- Use check_kernel_devel return code as appropriate + +* Fri Aug 23 2024 Nicolas Chauvet - 0.5.10-4 +- Change check_kernel_devel() to return instead of exit + +* Fri Aug 23 2024 Nicolas Chauvet - 0.5.10-3 +- akmods --from-init only operates on current kernel + +* Fri Aug 23 2024 Nicolas Chauvet - 0.5.10-2 +- Deprecate akmods-shutdown script + +* Fri Aug 23 2024 Nicolas Chauvet - 0.5.10-1 +- Bump to akmods 0.5.10 + +* Fri Aug 23 2024 Nicolas Chauvet - 0.5.9-8 +- Only check for default_kernel is no value - rhbz#2293047 + +* Fri Aug 23 2024 Nicolas Chauvet - 0.5.9-7 +- Revert "Call Init before the argument parser" + +* Fri Aug 23 2024 Nicolas Chauvet - 0.5.9-6 +- Switch to use sdubby alternatives to grubby + +* Fri Aug 23 2024 Nicolas Chauvet - 0.5.9-5 +- Drop older rhel and use -core + +* Fri Aug 23 2024 Nicolas Chauvet - 0.5.9-4 +- Drop older rhel cases + +* Mon Aug 19 2024 Jonathan Wakely - 0.5.9-3 +- Fix bug URLs in man page + +* Wed Jul 17 2024 Fedora Release Engineering - 0.5.9-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild + +* Thu Jul 04 2024 Nicolas Chauvet - 0.5.9-1 +- akmods release 0.5.9 + +* Thu Jul 04 2024 Hans de Goede - 0.5.8-10 +- Fix intel-ipu6-kmod installation with kernel >= 6.10 + +* Thu Jul 04 2024 Marius Schwarz - 0.5.8-9 +- Call Init before the argument parser + +* Mon Jan 22 2024 Fedora Release Engineering - 0.5.8-8 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + +* Fri Jan 19 2024 Fedora Release Engineering - 0.5.8-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + +* Tue Dec 05 2023 Nicolas Chauvet - 0.5.8-6 +- Workaround for rhbz#1889136 when localpkg_gpgcheck=True + * Wed Jul 19 2023 Fedora Release Engineering - 0.5.8-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild -* Fri May 5 2023 Nicolas Chauvet - 0.5.8-1 +* Fri May 05 2023 Nicolas Chauvet - 0.5.8-1 - Don't emit weak-deps from deprecated arches on all - Allow akmods --rebuild to force rebuild+reinstall - rhbz#2140012 - ensure to build for grub or systemd-boot default kernel - rhbz#2124086 - Drop "which" as akmods dependency -* Wed Jan 18 2023 Fedora Release Engineering - 0.5.7-10 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild -* Wed Jul 20 2022 Fedora Release Engineering - 0.5.7-9 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild - -* Wed May 04 2022 Nicolas Chauvet - 0.5.7-8 -- Fix logrotate permission access to /var/log/akmods directory - rhbz#2078490 -- Rename logrotate config file - -* Wed Mar 09 2022 Timothée Ravier - 0.5.7-7 -- Use 'Require' instead of 'Suggest' for kernel*-devel packages. - -* Thu Jan 27 2022 Nicolas Viéville - 0.5.7-6 -- Adapt usage of lockfile to systemd-tmpfiles -- Re-locate akmods logs in /var/log - -* Wed Jan 26 2022 Timothée Ravier - 0.5.7-5 -- Use kernel*-core variants in conditional Suggests - -* Wed Jan 19 2022 Fedora Release Engineering - 0.5.7-4 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild - -* Mon Dec 20 2021 Nicolas Chauvet - 0.5.7-3 -- Drop perl-interpeter -- Drop akmodsinit -- Only use preset on rhel -- kernel-devel-matched support - see also https://src.fedoraproject.org/rpms/akmods/pull-request/7 - -* Fri Dec 10 2021 Nicolas Chauvet - 0.5.7-2 -- Bump kmodtool requirement -- Rename kABI list -- Drop EL6 support -- Switch to distro agnostic deps - -* Fri Oct 22 2021 Nicolas Viéville - 0.5.7-1 -- Add local akmods CA signing keys and support tools to sign modules for - Secure boot thanks to Stanislas Leduc -- Add akmods-keygen service to generate MOK key pair on first run - -* Fri Oct 22 2021 Nicolas Viéville - 0.5.6-29 -- Remove trailing spaces and clean-up -- Use %%{name} when possible -- Convert if statement from "[!] $variable" to "[!] -n $variable" -- Fix kernel list build when parsing command line options -- Ensure to build for grub default kernel -- Improve detection of already installed (weak-)modules in akmods (RHEL) -- akmods uses logrotate and clean-up /var/cache/akmods sub-directories of - old logs and rpm files from no more installed kmod packages - (rhbz #1542658). - -* Wed Jul 21 2021 Fedora Release Engineering - 0.5.6-28 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild - -* Mon Jan 25 2021 Fedora Release Engineering - 0.5.6-27 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild - -* Mon Jul 27 2020 Fedora Release Engineering - 0.5.6-26 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild - -* Tue Jan 28 2020 Fedora Release Engineering - 0.5.6-25 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild - -* Wed Nov 20 2019 Nicolas Viéville - 0.5.6-24 -- Check kernel presence differently for systemd-boot machines - rhbz#1769144 - -* Wed Oct 16 2019 Leigh Scott - 0.5.6-23 -- Add requires kernel-abi-whitelists for RHEL - -* Wed Jul 24 2019 Fedora Release Engineering - 0.5.6-22 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild - -* Mon May 20 2019 Nicolas Chauvet - 0.5.6-21 -- Add check for rhel8 - -* Wed May 15 2019 Nicolas Viéville - 0.5.6-20 -- Fix akmodsposttrans after kernel update/install on Fedora >= 28 and - RHEL >= 7 - rhbz#1709055 - -* Thu Feb 28 2019 Alexander Larsson - 0.5.6-19 -- Support ostree/silverblue builds - rhbz#1667014 - -* Thu Feb 28 2019 Hans de Goede -- Do not fail when the old initscripts pkg is not installed - rhbz#1680121 - -* Thu Jan 31 2019 Fedora Release Engineering - 0.5.6-18 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild - -* Mon Nov 05 2018 Nicolas Chauvet - 0.5.6-17 -- Don't enforce target arch - rhbz#1644430 -- Rework log file path -- Avoid using /usr/lib/modules for el6 compat - -* Thu Jul 12 2018 Fedora Release Engineering - 0.5.6-16 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild - -* Mon Mar 26 2018 Nicolas Chauvet - 0.5.6-15 -- Add inihibitor for akmods@.service -- Use restart on akmodsposttrans - -* Mon Mar 26 2018 Nicolas Chauvet - 0.5.6-14 -- Switch to always retry by default -- Drop akmods preset by f28 -- Don't enable service on ah -- Test a rw directory - -* Wed Feb 07 2018 Fedora Release Engineering - 0.5.6-13 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild - -* Wed Dec 13 2017 Nicolas Chauvet - 0.5.6-12 -- Update kernel posttrans method - rhbz#1518401 - -* Thu Aug 03 2017 Nicolas Chauvet - 0.5.6-11 -- Rework kernel-devel requires on el - -* Thu Aug 03 2017 Nicolas Chauvet - 0.5.6-10 -- Enable suggests on fedora -- Add back el6 support in spec -- Add Requires elfutils-libelf-devel - -* Wed Jul 26 2017 Fedora Release Engineering - 0.5.6-9 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild - -* Thu Jul 13 2017 Petr Pisar - 0.5.6-8 -- perl dependency renamed to perl-interpreter - - -* Thu May 4 2017 Hans de Goede - 0.5.6-7 -- "udevadm trigger" may have bad side-effects (rhbz#454407) instead - look for modalias files under /sys/devices and call modprobe directly -- Fix exit status when no akmod packages are installed, so that systemd - does not consider the akmods.service as having failed to start - -* Wed May 3 2017 Hans de Goede - 0.5.6-6 -- Run "udevadm trigger" and "systemctl restart systemd-modules-load.service" - when new kmod packages have been build and installed so that the new - modules may be used immediately without requiring a reboot - -* Mon Mar 6 2017 Hans de Goede - 0.5.6-5 -- Add LICENSE file (rhbz#1422918) - -* Fri Feb 24 2017 Hans de Goede - 0.5.6-4 -- Replace %%{_prefix}/lib/systemd/system-preset with %%{_presetdir} - -* Thu Feb 16 2017 Hans de Goede - 0.5.6-3 -- Submit to Fedora for package review - -* Mon Nov 28 2016 Nicolas Chauvet - 0.5.6-2 -- Use Suggests kernel-devel weak-dependency - see rfbz#3386 - -* Fri Oct 14 2016 Richard Shaw - 0.5.6-1 -- Disable shutdown systemd service file by default. -- Remove modprobe line from main service file. - -* Wed Aug 17 2016 Sérgio Basto - 0.5.4-3 -- New release - -* Sun Jan 03 2016 Nicolas Chauvet - 0.5.4-2 -- Revert conflicts kernel-debug-devel - -* Thu Jul 23 2015 Richard Shaw - 0.5.4-1 -- Do not mark a build as failed when only installing the RPM fails. -- Run akmods-shutdown script instead of akmods on shutdown. -- Add systemd preset file to enable services by default. - -* Wed Jul 15 2015 Richard Shaw - 0.5.3-2 -- Add package conflicts to stop pulling in kernel-debug-devel, fixes BZ#3386. -- Add description for the formatting of the parameter, BZ#3580. -- Update static man pages and clean them up. -- Fixed another instance of TMPDIR causing issues. -- Added detection of dnf vs yum to akmods, fixed BZ#3481. - -* Wed Apr 1 2015 Richard Shaw - 0.5.2-1 -- Fix temporary directory creation when TMPDIR environment variable is set, - fixes BZ#2596. -- Update systemd scripts to use macros. -- Fix akmods run on shutdown systemd unit file, fixes BZ#3503. - -* Sun Nov 16 2014 Nicolas Chauvet - 0.5.1-4 -- Fix akmods on armhfp - rfbz#3117 -- Use yum instead of rpm to install packages - rfbz#3350 - Switch to a better date format - -* Fri Jan 11 2013 Richard Shaw - 0.5.1-3 -- Really fix akmods.service.in. - -* Fri Jun 01 2012 Richard Shaw - 0.5.1-2 -- Add service file to run again on shutdown. -- Add conditional for Fedora 18 to specify correct systemd graphical service. - -* Thu Apr 12 2012 Nicolas Chauvet - 0.4.0-4 -- Rebuilt - -* Tue Mar 20 2012 Richard Shaw - 0.4.0-3 -- Add additional error output if the needed kernel development files are not - installed. (Fixes #561) - -* Mon Mar 05 2012 Richard Shaw - 0.4.0-2 -- Remove remaining references to previous Fedora releases -- Remove legacy SysV init script from CVS. -- Added man page for akmods and cleaned up man page for akmodsbuild. - -* Tue Feb 07 2012 Nicolas Chauvet - 0.4.0-1 -- Update for UsrMove support -- Remove unused references to older fedora -- Change Requires from kernel-devel to kernel-devel-uname-r From c2d86c5f1c8e33a8e792b8b4431b511cbc102ca4 Mon Sep 17 00:00:00 2001 From: Leigh Scott Date: Sat, 3 May 2025 20:22:50 +0100 Subject: [PATCH 55/79] Fix changelog From f3b30d28b67cd9ac2da54bbe92e724b65d889e2a Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 23 Jul 2025 16:51:16 +0000 Subject: [PATCH 56/79] Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild From 9b91b410e792a804c65b197cdf82b94df229f7ff Mon Sep 17 00:00:00 2001 From: Daniel Hast Date: Tue, 2 Sep 2025 20:03:29 -0400 Subject: [PATCH 57/79] fix: apply shellcheck recommendations Ran ShellCheck against the akmods shell scripts and applied most of the recommendations, which addresses a number of subtle issues with shell script functionality. These changes shouldn't have any impact on script behavior, but improve clarity or avoid potential unexpected behavior (such as quoting variable expansions to avoid unintended shell splitting/globbing). Signed-off-by: Daniel Hast --- 95-akmodsposttrans.install | 6 +-- akmods | 81 ++++++++++++++++++++++---------------- akmods-ostree-post | 14 +++---- akmodsbuild | 64 +++++++++++++++--------------- 4 files changed, 89 insertions(+), 76 deletions(-) diff --git a/95-akmodsposttrans.install b/95-akmodsposttrans.install index b66551c..93e6b42 100755 --- a/95-akmodsposttrans.install +++ b/95-akmodsposttrans.install @@ -47,11 +47,11 @@ case "${COMMAND}" in /bin/systemctl is-active system-update.target &>/dev/null RET=$? - [ $RET == 0 ] && exit 0 + [[ $RET == 0 ]] && exit 0 - /bin/systemctl restart akmods@${KERNEL_VERSION}.service --no-block >/dev/null 2>&1 + /bin/systemctl restart "akmods@${KERNEL_VERSION}.service" --no-block >/dev/null 2>&1 else - nohup /usr/sbin/akmods --from-kernel-posttrans --kernels ${KERNEL_VERSION} > /dev/null 2>&1 & + nohup /usr/sbin/akmods --from-kernel-posttrans --kernels "${KERNEL_VERSION}" > /dev/null 2>&1 & fi exit 0 ;; diff --git a/akmods b/akmods index ff62faa..f796b14 100644 --- a/akmods +++ b/akmods @@ -53,7 +53,7 @@ last_message="" function check_plymouth() { which plymouth > /dev/null 2> /dev/null - if [[ $? -eq 1 ]] + if [[ "$?" -eq 1 ]] then no_plymouth=1 return 0 @@ -65,9 +65,9 @@ function check_plymouth() { # new or del, msg akmods_echo_plymouth(){ - if [[ $no_plymouth -eq 0 ]] + if [[ "$no_plymouth" -eq 0 ]] then - if [[ $1 -eq 1 ]] + if [[ "$1" -eq 1 ]] then plymouth display-message --text="$2" last_message=$2 @@ -91,7 +91,7 @@ akmods_echo() shift # output to console - if (( ${verboselevel} >= ${this_verbose} )) ; then + if (( verboselevel >= this_verbose )) ; then if [[ "${1}" == "--success" ]] ; then echo_success continue_line="" @@ -110,7 +110,7 @@ akmods_echo() elif [[ "${1}" == "-n" ]] ; then continue_line="true" fi - echo "$@" >&${this_fd} + echo "$@" >&"${this_fd}" fi # no need to print the status flags in the logs @@ -124,11 +124,11 @@ akmods_echo() fi # global logfile - echo "$(date +%Y/%m/%d\ %H:%M:%S) akmods: $@" >> "/var/log/akmods/akmods.log" + echo "$(date +%Y/%m/%d\ %H:%M:%S) akmods: $*" >> "/var/log/akmods/akmods.log" # the kmods logfile as well, if we work on a kmod if [[ -n "${kmodlogfile}" ]] ; then - echo "$(date +%Y/%m/%d\ %H:%M:%S) akmods: $@" >> "${kmodlogfile}" + echo "$(date +%Y/%m/%d\ %H:%M:%S) akmods: $*" >> "${kmodlogfile}" fi } @@ -140,7 +140,7 @@ finally() # remove lockfile rm -f /var/cache/akmods/.lockfile - exit ${1:-128} + exit "${1:-128}" } # Make sure finally() is run regardless of reason for exiting. @@ -148,7 +148,7 @@ trap "finally" ABRT HUP INT QUIT create_tmpdir() { - if ! tmpdir="$(mktemp -d -p /tmp ${myprog}.XXXXXXXX)/" ; then + if ! tmpdir="$(mktemp -d -p /tmp "${myprog}.XXXXXXXX")/" ; then akmods_echo 2 1 "ERROR: failed to create tmpdir." akmods_echo 2 1 --failure ; return 1 fi @@ -169,11 +169,13 @@ remove_tmpdir() cleanup_cachedir () { - for one_file in $(ls /var/cache/akmods/*/* 2>/dev/null | \ - grep -v "$(ls -I "*rescue*" /boot/vmlinuz-* | \ - sed 's%.*vmlinuz-%%g')") ; do - if $(grep -qE ".*\.rpm$" <<< "${one_file}") ; then - if ! $(rpm -q "$(basename ${one_file%.rpm})" >/dev/null) ; then + local excluded + excluded=$(find /boot -name 'vmlinuz-*' '!' -name '*rescue*' 2>/dev/null | sed 's/.*vmlinuz-//') + local -a file_list + mapfile -t file_list < <(find /var/cache/akmods -mindepth 3 2>/dev/null | grep -Fv -f <(echo "${excluded}")) + for one_file in "${file_list[@]}"; do + if grep -q ".*\.rpm$" <<< "${one_file}" ; then + if ! rpm -q "$(basename "${one_file%.rpm}")" >/dev/null ; then rm -f "${one_file}" fi else @@ -305,10 +307,11 @@ check_default_kernel() default_kernel="" fi - if [[ x${default_kernel} == x"$(uname -r)" ]] ; then - local _kernels="${default_kernel}" + local _kernels + if [[ "${default_kernel}" == "$(uname -r)" ]] ; then + _kernels="${default_kernel}" else - local _kernels="${default_kernel} $(uname -r)" + _kernels="${default_kernel} $(uname -r)" fi for _kernel in ${_kernels} ; do @@ -375,7 +378,7 @@ buildinstall_kmod() fi # result - if (( ! ${returncode} == 0 )) ; then + if (( returncode != 0 )) ; then if [[ -n "${continue_line}" ]] ; then akmods_echo 1 2 --failure fi @@ -395,12 +398,14 @@ buildinstall_kmod() akmods_echo_plymouth 0 "" akmods_echo_plymouth 1 "akmod: Installing ${this_kmodsrpm}..." akmods_echo 1 4 "Installing newly built rpms" + local -a rpm_paths + mapfile -t rpm_paths < <(find "${tmpdir}results" -type f -name '*.rpm' | grep -v debuginfo) if [[ -f /usr/bin/dnf ]] ; then akmods_echo 1 4 "DNF detected" - dnf -y ${pkg_install:-install} --nogpgcheck --disablerepo='*' $(find "${tmpdir}results" -type f -name '*.rpm' | grep -v debuginfo) >> "${kmodlogfile}" 2>&1 + dnf -y "${pkg_install:-install}" --nogpgcheck --disablerepo='*' "${rpm_paths[@]}" >> "${kmodlogfile}" 2>&1 else akmods_echo 1 4 "DNF not found, using YUM instead." - yum -y ${pkg_install:-install} --nogpgcheck --disablerepo='*' $(find "${tmpdir}results" -type f -name '*.rpm' | grep -v debuginfo) >> "${kmodlogfile}" 2>&1 + yum -y "${pkg_install:-install}" --nogpgcheck --disablerepo='*' "${rpm_paths[@]}" >> "${kmodlogfile}" 2>&1 fi local returncode=$? @@ -408,7 +413,7 @@ buildinstall_kmod() cp "${tmpdir}results/"* "/var/cache/akmods/${this_kmodname}/" # everything fine? - if (( ${returncode} != 0 )) ; then + if (( returncode != 0 )) ; then if [[ -n "${continue_line}" ]] ; then akmods_echo 1 2 --failure fi @@ -445,7 +450,8 @@ check_kmod_up2date() return 1 fi - local kmodpackage_file="$(modinfo ${this_kmodname} -k ${this_kernelver} -n 2>/dev/null)" + local kmodpackage_file + kmodpackage_file="$(modinfo "${this_kmodname}" -k "${this_kernelver}" -n 2>/dev/null)" # kmod present, even with weak-modules? if [[ ! -n "${kmodpackage_file}" ]] && [[ ! -d /lib/modules/${this_kernelver}/extra/${this_kmodname}/ ]] ; then @@ -462,12 +468,13 @@ check_kmod_up2date() fi # kmod up2date? + local kmodpackage # Weak module symlink case - if [ -n "${kmodpackage_file}" ] && [ -h "${kmodpackage_file}" ] && $(echo "${kmodpackage_file}" | grep -q "weak-updates") ; then - local kmodpackage="$(rpm -qf $(readlink -e ${kmodpackage_file}) 2> /dev/null)" + if [ -n "${kmodpackage_file}" ] && [ -h "${kmodpackage_file}" ] && echo "${kmodpackage_file}" | grep -q "weak-updates" ; then + kmodpackage="$(rpm -qf "$(readlink -e "${kmodpackage_file}")" 2> /dev/null)" # Regular module file case else - local kmodpackage="$(rpm -qf /lib/modules/${this_kernelver}/extra/${this_kmodname}/ 2> /dev/null)" + kmodpackage="$(rpm -qf "/lib/modules/${this_kernelver}/extra/${this_kmodname}/" 2> /dev/null)" fi if [[ ! -n "${kmodpackage}" ]] ; then # seems we didn't get what we wanted @@ -475,8 +482,10 @@ check_kmod_up2date() akmods_echo 1 2 -n "Warning: Could not determine what package owns /lib/modules/${this_kernelver}/extra/${this_kmodname}/" return 0 fi - local kmodver=$(rpm -q --qf '%{EPOCH}:%{VERSION}-%{RELEASE}\n' "${kmodpackage}" | sed 's|(none)|0|; s!\.\(fc\|el\|lvn\)[0-9]*!!g') - local akmodver=$(rpm -qp --qf '%{EPOCH}:%{VERSION}-%{RELEASE}\n' /usr/src/akmods/"${this_kmodname}"-kmod.latest | sed 's|(none)|0|; s!\.\(fc\|el\|lvn\)[0-9]*!!g') + local kmodver + kmodver=$(rpm -q --qf '%{EPOCH}:%{VERSION}-%{RELEASE}\n' "${kmodpackage}" | sed 's|(none)|0|; s!\.\(fc\|el\|lvn\)[0-9]*!!g') + local akmodver + akmodver=$(rpm -qp --qf '%{EPOCH}:%{VERSION}-%{RELEASE}\n' /usr/src/akmods/"${this_kmodname}"-kmod.latest | sed 's|(none)|0|; s!\.\(fc\|el\|lvn\)[0-9]*!!g') rpmdev-vercmp "${kmodver}" "${akmodver}" &>/dev/null local retvalue=$? @@ -503,7 +512,8 @@ check_kmods() akmods_echo 1 2 -n "Checking kmods exist for ${this_kernelver}" for akmods_kmodfile in /usr/src/akmods/*-kmod.latest ; do - local this_kmodname="$(basename ${akmods_kmodfile%%-kmod.latest})" + local this_kmodname + this_kmodname="$(basename "${akmods_kmodfile%%-kmod.latest}")" # actually check this akmod? if [[ -n "${akmods}" ]] ; then @@ -516,7 +526,7 @@ check_kmods() fi # go - if ! check_kmod_up2date ${this_kernelver} ${this_kmodname} ; then + if ! check_kmod_up2date "${this_kernelver}" "${this_kmodname}" ; then # okay, kmod wasn't found or is not up2date if [[ -n "${continue_line}" ]] ; then akmods_echo 1 2 --success @@ -534,14 +544,15 @@ check_kmods() fi fi - local this_kmodverrel="$(rpm -qp --qf '%{VERSION}-%{RELEASE}' "${akmods_kmodfile}" | sed 's!\.\(fc\|el\|lvn\)[0-9]*!!g' )" + local this_kmodverrel + this_kmodverrel="$(rpm -qp --qf '%{VERSION}-%{RELEASE}' "${akmods_kmodfile}" | sed 's!\.\(fc\|el\|lvn\)[0-9]*!!g' )" if [[ ! -n "${alwaystry}" ]] && [[ -e "/var/cache/akmods/${this_kmodname}/${this_kmodverrel}-for-${this_kernelver}".failed.log ]] ; then akmods_echo 1 2 -n "Ignoring ${this_kmodname}-kmod as it failed earlier" akmods_echo 1 2 --warning local someignored="true" else akmods_echo 1 2 -n "Building and installing ${this_kmodname}-kmod" - buildinstall_kmod ${this_kernelver} ${this_kmodname} ${akmods_kmodfile} ${this_kmodverrel} + buildinstall_kmod "${this_kernelver}" "${this_kmodname}" "${akmods_kmodfile}" "${this_kmodverrel}" local returncode=$? if [[ "$returncode" == "0" ]] ; then akmods_echo 1 2 --success @@ -568,7 +579,7 @@ check_kmods() # akmods for newly installed akmod rpms as wells as akmods.service run # after udev and systemd-modules-load.service have tried to load modules - if [[ -n "${somesucceeded}" ]] && [[ ${this_kernelver} = "$(uname -r)" ]] ; then + if [[ -n "${somesucceeded}" ]] && [[ "${this_kernelver}" == "$(uname -r)" ]] ; then find /sys/devices -name modalias -print0 | xargs -0 cat | xargs modprobe -a -b -q if [ -f /usr/bin/systemctl ] ; then systemctl restart systemd-modules-load.service @@ -653,11 +664,11 @@ while [ "${1}" ] ; do shift ;; --verbose) - let verboselevel++ + (( verboselevel++ )) shift ;; --quiet) - let verboselevel-- + (( verboselevel-- )) shift ;; --help) @@ -687,7 +698,7 @@ fi # go for kernel in ${kernels} ; do - check_kmods ${kernel} + check_kmods "${kernel}" done # finished :) diff --git a/akmods-ostree-post b/akmods-ostree-post index 517e1b3..747d0ed 100644 --- a/akmods-ostree-post +++ b/akmods-ostree-post @@ -43,7 +43,7 @@ finally() # remove tmpfiles remove_tmpdir - exit ${1:-128} + exit "${1:-128}" } # Make sure finally() is run regardless of reason for exiting. @@ -51,7 +51,7 @@ trap "finally" ABRT HUP INT QUIT create_tmpdir() { - if ! tmpdir="$(mktemp -d -p /tmp ${myprog}.XXXXXXXX)/" ; then + if ! tmpdir="$(mktemp -d -p /tmp "${myprog}.XXXXXXXX")/" ; then echo "ERROR: failed to create tmpdir." >&2 finally 1 fi @@ -79,24 +79,24 @@ for kernel in ${kernels} ; do echo "Building ${srpm} for kernel ${kernel}" # Note: This builds as root, but this is pretty safe because its happening in the ostree %post sandbox. # In fact, given that /usr is a rofiles-fuse mount no other user can access /usr in this sandbox anyway. - akmodsbuild --quiet --kernels ${kernel} --outputdir ${tmpdir}results --logfile "${tmpdir}/akmodsbuild.log" "${srpm}" 2>&1 + akmodsbuild --quiet --kernels "${kernel}" --outputdir "${tmpdir}results" --logfile "${tmpdir}/akmodsbuild.log" "${srpm}" 2>&1 returncode=$? - if (( ! ${returncode} == 0 )); then + if (( returncode != 0 )); then finally 1 fi done for f in $(find "${tmpdir}results" -type f -name '*.rpm' | grep -v debuginfo) ; do - rpm2cpio $f | cpio --quiet -D / -id + rpm2cpio "${f}" | cpio --quiet -D / -id returncode=$? - if (( ! ${returncode} == 0 )); then + if (( returncode != 0 )); then echo "Extracting $f failed:" 2>&1 finally 1 fi done for kernel in ${kernels} ; do - depmod -v ${kernel} 2>&1 + depmod -v "${kernel}" 2>&1 done finally 0 diff --git a/akmodsbuild b/akmodsbuild index 848c392..08a4cf4 100644 --- a/akmodsbuild +++ b/akmodsbuild @@ -64,7 +64,7 @@ init () # SRPMS available? for srpm in ${srpms}; do - if [[ ! -r ${srpm} ]] ; then + if [[ ! -r "${srpm}" ]] ; then echo "ERROR: Can't find SRPM ${srpm}" exit 1 fi @@ -81,19 +81,19 @@ init () # make sure this is a number - if ! (( ${numberofjobs} > 0 )) ; then + if ! (( numberofjobs > 0 )) ; then echo "Warning: using hardcoded defaut value for number of jobs" numberofjobs=2 fi ## preparations # tmpdir - if ! tmpdir="$(mktemp -d -p /tmp ${myprog}.XXXXXXXX)" ; then + if ! tmpdir="$(mktemp -d -p /tmp "${myprog}.XXXXXXXX")" ; then echo "ERROR: Could create tempdir." exit 1 fi - # buildtreee + # buildtree mkdir "${tmpdir}"/{BUILD,SOURCES,SPECS,SRPMS,RPMS,RPMS/"${target}"} # logfile @@ -101,7 +101,7 @@ init () logfile="${tmpdir}/logfile" fi - if ( [[ -e "${logfile}" ]] && [[ ! -w "${logfile}" ]] ) || ! touch "${logfile}" ; then + if { [[ -e "${logfile}" ]] && [[ ! -w "${logfile}" ]] ; } || ! touch "${logfile}" ; then echo "ERROR: Could not write logfile." finally exit 1 @@ -143,12 +143,12 @@ akmods_echo() fi # output to console - if (( ${verboselevel} >= ${this_verbose} )) ; then - echo "$@" >&${this_fd} + if (( verboselevel >= this_verbose )) ; then + echo "$@" >&"${this_fd}" fi # global logfile - if [[ ! -n ${notlogfile} ]] ; then + if [[ ! -n "${notlogfile}" ]] ; then echo "$@" >> "${logfile}" fi } @@ -159,8 +159,8 @@ watch_rpmbuild() # background function to show rpmbuild progress # does't use akmods_echo here; this stage handles the output on its own # (seperate process and there is no need to log this) - if (( ${verboselevel} == 2 )) ; then - tail --pid ${1} -n +1 -s 0.1 -f ${2} 2>/dev/null | grep --line-buffered -e '%prep' -e '%build' -e '%install' -e '%clean' | while read line ; do + if (( verboselevel == 2 )) ; then + tail --pid "${1}" -n +1 -s 0.1 -f "${2}" 2>/dev/null | grep --line-buffered -e '%prep' -e '%build' -e '%install' -e '%clean' | while read -r line ; do if [[ "${line}" != "${line##*prep}" ]] ; then echo -n "prep " elif [[ "${line}" != "${line##*build}" ]] ; then @@ -172,8 +172,8 @@ watch_rpmbuild() # last linefeed is done by the caller fi done - elif (( ${verboselevel} > 2 )) ; then - tail --pid ${1} -n +1 -s 0.1 -f ${2} + elif (( verboselevel > 2 )) ; then + tail --pid "${1}" -n +1 -s 0.1 -f "${2}" fi } @@ -194,31 +194,32 @@ process_srpm() --define "_rpmdir ${tmpdir}/RPMS" \ --define "_smp_mflags -j${numberofjobs}" \ --define "kernels ${kernels}" \ - --target ${target} \ + --target "${target}" \ --rebuild "${source_rpm}" 2>&1 | tee -a "${logfile}" > "${tmpdir}/.joblog" & local rpmbuild_jobid=$! # show progress - if (( ${verboselevel} >= 2 )) ; then - watch_rpmbuild ${rpmbuild_jobid} "${tmpdir}/.joblog" 2> /dev/null & + if (( verboselevel >= 2 )) ; then + watch_rpmbuild "${rpmbuild_jobid}" "${tmpdir}/.joblog" 2> /dev/null & local watch_jobid=$! fi # wait for rpmbuild - wait ${rpmbuild_jobid} - local rpmbuild_returncode=$(tail -n 1 "${tmpdir}/.jobexit") + wait "${rpmbuild_jobid}" + local rpmbuild_returncode + rpmbuild_returncode=$(tail -n 1 "${tmpdir}/.jobexit") unset rpmbuild_jobid # give watch_rpmbuild a moment to catch up; kill it if it does not - if (( ${verboselevel} >= 2 )) ; then + if (( verboselevel >= 2 )) ; then sleep 0.5 - kill ${watch_jobid} &> /dev/null + kill "${watch_jobid}" &> /dev/null unset watch_jobid fi # did rpmbuild succeed? - if (( ${rpmbuild_returncode} != 0 )) ; then + if (( rpmbuild_returncode != 0 )) ; then # linefeed: akmods_echo 1 2 "" @@ -226,15 +227,16 @@ process_srpm() akmods_echo 2 2 --not-logfile "--- " tail -n 35 "${tmpdir}/.joblog" >&2 akmods_echo 2 2 --not-logfile "---" - return ${rpmbuild_returncode} + return "${rpmbuild_returncode}" fi # finish status for watch_rpmbuild - if (( ${verboselevel} >= 2 )) ; then - akmods_echo 1 2 -n "Successfull; " + if (( verboselevel >= 2 )) ; then + akmods_echo 1 2 -n "Successful; " fi - local rpms_built="$(cd "${tmpdir}"/RPMS/"${target}" ; echo *)" + local rpms_built + rpms_built="$(cd "${tmpdir}"/RPMS/"${target}" || exit ; echo *)" if ! mv "${tmpdir}/RPMS/${target}/"* "${outputdir}" ; then # linefeed: @@ -244,11 +246,11 @@ process_srpm() return 128 fi - if (( ${verboselevel} == 1 )) ; then + if (( verboselevel == 1 )) ; then for rpm in ${rpms_built}; do echo "${outputdir%%/}/${rpm}" done - elif (( ${verboselevel} >= 2 )) ; then + elif (( verboselevel >= 2 )) ; then akmods_echo 1 2 "Saved ${rpms_built} in ${outputdir%%/}/" fi @@ -311,11 +313,11 @@ while [ "${1}" ] ; do shift ;; -v|--verbose) - let verboselevel++ + (( verboselevel++ )) shift ;; -q|--quiet) - let verboselevel-- + (( verboselevel-- )) shift ;; -h|--help) @@ -343,12 +345,12 @@ init # go for srpm in ${srpms}; do - process_srpm ${srpm} + process_srpm "${srpm}" returncode=$? - if (( ${returncode} != 0 )) ; then + if (( returncode != 0 )) ; then finally - exit ${returncode} + exit "${returncode}" fi done From df1211cf1ec34fa3b9ceda9ec98a74860f64f8cb Mon Sep 17 00:00:00 2001 From: Leigh Scott Date: Sat, 3 May 2025 20:22:50 +0100 Subject: [PATCH 58/79] Fix changelog From bc81288496d7de511f4462552c84fc7c192352d3 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 23 Jul 2025 16:51:16 +0000 Subject: [PATCH 59/79] Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild From eb27fa99182887d5af14b82f56bc43e60829e5b3 Mon Sep 17 00:00:00 2001 From: Nicolas Chauvet Date: Tue, 16 Sep 2025 20:24:05 +0200 Subject: [PATCH 60/79] Drop nohup usage --- 95-akmodsposttrans.install | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/95-akmodsposttrans.install b/95-akmodsposttrans.install index 93e6b42..e4912a5 100755 --- a/95-akmodsposttrans.install +++ b/95-akmodsposttrans.install @@ -41,19 +41,13 @@ fi case "${COMMAND}" in add) - # needs to run in background as rpmdb might be locked otherwise - if [ -e /bin/systemctl ] ; then - # Exit early if system-update.target is active - rhbz#1518401 - /bin/systemctl is-active system-update.target &>/dev/null - RET=$? + # Exit early if system-update.target is active - rhbz#1518401 + /bin/systemctl is-active system-update.target &>/dev/null + RET=$? - [[ $RET == 0 ]] && exit 0 + [[ $RET == 0 ]] && exit 0 - /bin/systemctl restart "akmods@${KERNEL_VERSION}.service" --no-block >/dev/null 2>&1 - else - nohup /usr/sbin/akmods --from-kernel-posttrans --kernels "${KERNEL_VERSION}" > /dev/null 2>&1 & - fi - exit 0 + /bin/systemctl restart "akmods@${KERNEL_VERSION}.service" --no-block >/dev/null 2>&1 ;; remove) # Nothing to do From c387dbb719f9dfaa4e9995ca2678d117001f09f7 Mon Sep 17 00:00:00 2001 From: Francis Montagnac Date: Tue, 16 Sep 2025 21:56:37 +0200 Subject: [PATCH 61/79] akmods: check_default_kernel is never called - rhbz#2376351 Signed-off-by: Nicolas Chauvet --- akmods | 5 ----- 1 file changed, 5 deletions(-) diff --git a/akmods b/akmods index f796b14..a01e5af 100644 --- a/akmods +++ b/akmods @@ -196,11 +196,6 @@ init () UMASK=022 umask ${UMASK} - # fall back to current kernel if user didn't provide one - if [[ ! -n "${kernels}" ]] ; then - kernels="$(uname -r)" - fi - # we get the echo_{success,failure} stuff from there if [[ -r /etc/rc.d/init.d/functions ]] ; then source /etc/rc.d/init.d/functions From e1da058ed2f430897e68482a9ed85fe9e1bfad01 Mon Sep 17 00:00:00 2001 From: Francis Montagnac Date: Tue, 16 Sep 2025 22:03:49 +0200 Subject: [PATCH 62/79] akmods: wrong calls to check_kernel_devel - rhbz#2376351 Signed-off-by: Nicolas Chauvet --- akmods | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/akmods b/akmods index a01e5af..6bcb082 100644 --- a/akmods +++ b/akmods @@ -310,7 +310,7 @@ check_default_kernel() fi for _kernel in ${_kernels} ; do - if [[ $(check_kernel_devel "${_kernel}" == 0) ]] ; then + if check_kernel_devel "${_kernel}" ; then kernels="${kernels} ${_kernel}" fi done @@ -605,7 +605,7 @@ while [ "${1}" ] ; do exit 1 fi - if [[ $(check_kernel_devel "${1}" != 0) ]] ; then + if ! check_kernel_devel "${1}" ; then echo "ERROR: kernel or kernel-devel required for ${1}" >&2 exit 1 fi From 4882031c241459d7750902598a8db4c74918963f Mon Sep 17 00:00:00 2001 From: Nicolas Chauvet Date: Tue, 16 Sep 2025 22:47:01 +0200 Subject: [PATCH 63/79] akmods: drop grubby symlink test --- akmods | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/akmods b/akmods index 6bcb082..d8ddff5 100644 --- a/akmods +++ b/akmods @@ -285,7 +285,7 @@ check_default_kernel() # IMPORTANT: "bootctl is-installed" check that systemd-boot is installed only. # It doesn't check if systemd-boot is the default loader. # So we assume grubby results if available - if [ ! -h /usr/sbin/grubby ] && command -v grubby >/dev/null 2>&1 ; then + if command -v grubby >/dev/null 2>&1 ; then default_kernel=$(grubby --default-kernel | sed -e 's/^.*vmlinuz-//') elif bootctl is-installed >/dev/null 2>&1 ; then # Leave jq as optional - isDefault requires systemd 253 From b2e2537720f1617e68cd1a88025bb019d3b5bfba Mon Sep 17 00:00:00 2001 From: Nicolas Chauvet Date: Mon, 22 Sep 2025 12:49:51 +0200 Subject: [PATCH 64/79] Drop global armv7hl target override and default --- akmodsbuild | 4 ---- 1 file changed, 4 deletions(-) diff --git a/akmodsbuild b/akmodsbuild index 08a4cf4..b8fc706 100644 --- a/akmodsbuild +++ b/akmodsbuild @@ -27,10 +27,6 @@ myver="0.5.6" # defaults that might get overwritten by user: kernels="$(uname -r)" -target="$(uname -m)" -if [[ "${target}" == "armv7l" ]] ; then - target="armv7hl" -fi numberofjobs=$(grep -c processor /proc/cpuinfo 2> /dev/null) verboselevel=2 outputdir="${PWD}" From ae0d4e1c76c8b91259d152a6eca9256b9692196b Mon Sep 17 00:00:00 2001 From: Nicolas Chauvet Date: Mon, 22 Sep 2025 13:47:22 +0200 Subject: [PATCH 65/79] Case for unspecified target - rhbz#2394562 --- akmodsbuild | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/akmodsbuild b/akmodsbuild index b8fc706..1069388 100644 --- a/akmodsbuild +++ b/akmodsbuild @@ -89,6 +89,15 @@ init () exit 1 fi + if [ -z "${target}" ] ; then + case "${kernels}" in + *x86_64_v4) target=x86_64_v4;; + *x86_64_v3) target=x86_64_v3;; + *x86_64_v2) target=x86_64_v2;; + *armv7hl) target=armv7hl;; + *) target="$(uname -m)" ;; + esac + fi # buildtree mkdir "${tmpdir}"/{BUILD,SOURCES,SPECS,SRPMS,RPMS,RPMS/"${target}"} From f85811c72d5715c527ab01a95ee4ee70d6f14164 Mon Sep 17 00:00:00 2001 From: Nicolas Chauvet Date: Mon, 22 Sep 2025 14:18:21 +0200 Subject: [PATCH 66/79] Rework sysusers --- akmods.spec | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/akmods.spec b/akmods.spec index 6ed6a9a..3d89659 100644 --- a/akmods.spec +++ b/akmods.spec @@ -26,6 +26,7 @@ Source17: akmods-kmodgenca Source18: akmods-keygen.target Source19: akmods-keygen@.service Source20: %{name}-tmpfiles.conf +Source21: akmods.sysusers.conf BuildArch: noarch @@ -93,11 +94,6 @@ after they were installed. %setup -q -c -T cp -p %{SOURCE9} %{SOURCE10} %{SOURCE15} . -# Create a sysusers.d config file -cat >akmods.sysusers.conf < Date: Mon, 22 Sep 2025 14:18:46 +0200 Subject: [PATCH 67/79] Drop nohup requires for rhel6 --- akmods.spec | 3 --- 1 file changed, 3 deletions(-) diff --git a/akmods.spec b/akmods.spec index 3d89659..10db04e 100644 --- a/akmods.spec +++ b/akmods.spec @@ -33,9 +33,6 @@ BuildArch: noarch BuildRequires: help2man # not picked up automatically -%if 0%{?rhel} == 6 -Requires: %{_bindir}/nohup -%endif Requires: %{_bindir}/flock Requires: %{_bindir}/time From 413f0417be5c181bb76878a2cca566712207917b Mon Sep 17 00:00:00 2001 From: Nicolas Chauvet Date: Mon, 22 Sep 2025 14:19:14 +0200 Subject: [PATCH 68/79] Update to 0.6.1 --- akmods | 2 +- akmods.spec | 2 +- akmodsbuild | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/akmods b/akmods index d8ddff5..d7ed0d3 100644 --- a/akmods +++ b/akmods @@ -37,7 +37,7 @@ # global vars myprog="akmods" -myver="0.6.0" +myver="0.6.1" kmodlogfile= continue_line="" tmpdir= diff --git a/akmods.spec b/akmods.spec index 10db04e..9f349c0 100644 --- a/akmods.spec +++ b/akmods.spec @@ -1,5 +1,5 @@ Name: akmods -Version: 0.6.0 +Version: 0.6.1 Release: %autorelease Summary: Automatic kmods build and install tool diff --git a/akmodsbuild b/akmodsbuild index 1069388..67354b0 100644 --- a/akmodsbuild +++ b/akmodsbuild @@ -23,7 +23,7 @@ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # myprog="akmodsbuild" -myver="0.5.6" +myver="0.6.1" # defaults that might get overwritten by user: kernels="$(uname -r)" From 91b528407487cfe49c116837d6cb888c7290e1f8 Mon Sep 17 00:00:00 2001 From: Nicolas Chauvet Date: Mon, 22 Sep 2025 15:13:45 +0200 Subject: [PATCH 69/79] Add akmods-sysusers.conf --- akmods.sysusers.conf | 1 + 1 file changed, 1 insertion(+) create mode 100644 akmods.sysusers.conf diff --git a/akmods.sysusers.conf b/akmods.sysusers.conf new file mode 100644 index 0000000..f505ad6 --- /dev/null +++ b/akmods.sysusers.conf @@ -0,0 +1 @@ +u akmods - 'User is used by akmods to build akmod packages' /var/cache/akmods/ - From 6756b5cdd7619b9e234fd1e6e5fb0e5313dfe5ee Mon Sep 17 00:00:00 2001 From: Nicolas Chauvet Date: Mon, 22 Sep 2025 15:50:53 +0200 Subject: [PATCH 70/79] Rework akmod.service installation --- akmods.service.in => akmods.service | 2 +- akmods.spec | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) rename akmods.service.in => akmods.service (90%) diff --git a/akmods.service.in b/akmods.service similarity index 90% rename from akmods.service.in rename to akmods.service index 22530d3..587913d 100644 --- a/akmods.service.in +++ b/akmods.service @@ -1,7 +1,7 @@ [Unit] Description=Builds and install new kmods from akmod packages ConditionPathExists=!/run/ostree-booted -Before=@SERVICE@ +Before=display-manager.service After=akmods-keygen.target Wants=akmods-keygen.target diff --git a/akmods.spec b/akmods.spec index 9f349c0..461531a 100644 --- a/akmods.spec +++ b/akmods.spec @@ -11,7 +11,7 @@ Source0: 95-akmods.preset Source1: akmods Source2: akmodsbuild Source3: akmods.h2m -Source6: akmods.service.in +Source6: akmods.service Source7: akmods-shutdown Source8: akmods-shutdown.service Source9: README @@ -122,9 +122,9 @@ install -pm 0755 %{SOURCE13} %{buildroot}%{_prefix}/lib/kernel/install.d/ mkdir -p \ %{buildroot}%{_unitdir} \ %{buildroot}%{_presetdir} -sed "s|@SERVICE@|display-manager.service|" %{SOURCE6} >\ - %{buildroot}%{_unitdir}/akmods.service + install -pm 0644 %{SOURCE0} %{buildroot}%{_presetdir}/ +install -pm 0644 %{SOURCE6} %{buildroot}%{_unitdir}/ install -pm 0755 %{SOURCE7} %{buildroot}%{_sbindir}/ install -pm 0644 %{SOURCE8} %{buildroot}%{_unitdir}/ install -pm 0644 %{SOURCE11} %{buildroot}%{_unitdir}/ From 9737ee61c0b2ee1f0655788dc092cee43dc2f4fe Mon Sep 17 00:00:00 2001 From: Nicolas Chauvet Date: Mon, 22 Sep 2025 15:51:36 +0200 Subject: [PATCH 71/79] Drop akmodsinit --- akmodsinit | 47 ----------------------------------------------- 1 file changed, 47 deletions(-) delete mode 100644 akmodsinit diff --git a/akmodsinit b/akmodsinit deleted file mode 100644 index 3f401c7..0000000 --- a/akmodsinit +++ /dev/null @@ -1,47 +0,0 @@ -#!/bin/bash - -# -# akmodinit Builds and install new kmods from akmod packages -# -# Author: Thorsten Leemhuis -# -# chkconfig: 2345 5 95 -# -# description: akmodsinit calls akmod during system boot to build and install -# kmods for the currently running kernel if neccessary. -# -# processname: akmodsd -# pidfile: /var/run/akmodsd.pid -# - -### BEGIN INIT INFO -# Provides: akmodsd -# Required-Start: $local_fs -# Required-Stop: $local_fs -# Default-Start: 2 3 4 5 -# Default-Stop: 0 1 6 -# Short-Description: Builds and install new kmods from akmod packages -# Description: akmodsinit calls akmod during system boot to build and install -# kmods for the currently running kernel if neccessary. -### END INIT INFO - -start_akmods () -{ - # build and install all kmods if neccessary - # for the currently running kernel (default in akmods) - /usr/sbin/akmods --from-init -} - - -# See how we were called. -case "$1" in - start|restart|reload|condrestart) - start_akmods - ;; - stop|status) - exit 0 - ;; - *) - echo $"Usage: $0 start" - exit 2 - ;; -esac From b363e421582e70d27bc36998825204836c524e2b Mon Sep 17 00:00:00 2001 From: Nicolas Chauvet Date: Wed, 1 Oct 2025 14:15:28 +0200 Subject: [PATCH 72/79] docs: drop grep Issuer from mokutil output --- README.secureboot | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.secureboot b/README.secureboot index 059977f..908b282 100644 --- a/README.secureboot +++ b/README.secureboot @@ -46,6 +46,6 @@ below. You can confirm the enrollment of the new keypair once the system rebooted with: - `mokutil --list-enrolled | grep Issuer` + `mokutil --list-enrolled or with: `mokutil --test-key /etc/pki/akmods/certs/public_key.der` From 602926dc32063b4fa463e1f768b37e1577e968d2 Mon Sep 17 00:00:00 2001 From: Nicolas Chauvet Date: Wed, 1 Oct 2025 16:06:24 +0200 Subject: [PATCH 73/79] akmods: add missing sysusers group --- akmods.sysusers.conf | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/akmods.sysusers.conf b/akmods.sysusers.conf index f505ad6..6dd7280 100644 --- a/akmods.sysusers.conf +++ b/akmods.sysusers.conf @@ -1 +1,3 @@ -u akmods - 'User is used by akmods to build akmod packages' /var/cache/akmods/ - +#Type Name ID GECOS Home directory Shell +g akmods - - - - +u akmods - 'User is used by akmods to build akmod packages' /var/cache/akmods/ - From b68a5b81ce71f76ff7b1e557dfd409adbc929131 Mon Sep 17 00:00:00 2001 From: Nicolas Chauvet Date: Wed, 1 Oct 2025 16:08:56 +0200 Subject: [PATCH 74/79] Update to 0.6.2 --- akmods | 2 +- akmods.spec | 2 +- akmodsbuild | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/akmods b/akmods index d7ed0d3..cdaa39a 100644 --- a/akmods +++ b/akmods @@ -37,7 +37,7 @@ # global vars myprog="akmods" -myver="0.6.1" +myver="0.6.2" kmodlogfile= continue_line="" tmpdir= diff --git a/akmods.spec b/akmods.spec index 461531a..0450a65 100644 --- a/akmods.spec +++ b/akmods.spec @@ -1,5 +1,5 @@ Name: akmods -Version: 0.6.1 +Version: 0.6.2 Release: %autorelease Summary: Automatic kmods build and install tool diff --git a/akmodsbuild b/akmodsbuild index 67354b0..23b0783 100644 --- a/akmodsbuild +++ b/akmodsbuild @@ -23,7 +23,7 @@ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # myprog="akmodsbuild" -myver="0.6.1" +myver="0.6.2" # defaults that might get overwritten by user: kernels="$(uname -r)" From edb1bd2b68b8eeec397797956785453758a31ad6 Mon Sep 17 00:00:00 2001 From: Nicolas Chauvet Date: Wed, 15 Oct 2025 16:40:00 +0200 Subject: [PATCH 75/79] Add compat for sysusers support --- akmods.spec | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/akmods.spec b/akmods.spec index 0450a65..88d3cef 100644 --- a/akmods.spec +++ b/akmods.spec @@ -32,6 +32,9 @@ BuildArch: noarch BuildRequires: help2man +# Needed for older branches el8+, noop on f43+ +%{?sysusers_requires_compat} + # not picked up automatically Requires: %{_bindir}/flock Requires: %{_bindir}/time @@ -143,6 +146,8 @@ help2man -N -i %{SOURCE3} -s 1 \ install -m0644 -D %{SOURCE21} %{buildroot}%{_sysusersdir}/akmods.conf +%pre +%sysusers_create_compat %{SOURCE21} %post %systemd_post akmods.service From 6b27509edfcacd847fcc7a530d3ebced606f8ac8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luan=20Vitor=20Simi=C3=A3o=20oliveira?= Date: Wed, 5 Nov 2025 20:58:54 -0300 Subject: [PATCH 76/79] fix: prevent akmods@ on offline update on fc43+ --- 95-akmodsposttrans.install | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/95-akmodsposttrans.install b/95-akmodsposttrans.install index e4912a5..407e9ac 100755 --- a/95-akmodsposttrans.install +++ b/95-akmodsposttrans.install @@ -42,7 +42,7 @@ fi case "${COMMAND}" in add) # Exit early if system-update.target is active - rhbz#1518401 - /bin/systemctl is-active system-update.target &>/dev/null + /usr/bin/systemctl -q is-active system-update-pre.target system-update.target RET=$? [[ $RET == 0 ]] && exit 0 From ec65894b43a9b20f9f1fd0258af191a3486a72c8 Mon Sep 17 00:00:00 2001 From: Mark K <7grrar1r+fedora@gmail.com> Date: Thu, 8 Jan 2026 00:37:27 +0100 Subject: [PATCH 77/79] fix cleanup_cachedir function --- akmods | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/akmods b/akmods index cdaa39a..9af6046 100644 --- a/akmods +++ b/akmods @@ -172,7 +172,7 @@ cleanup_cachedir () local excluded excluded=$(find /boot -name 'vmlinuz-*' '!' -name '*rescue*' 2>/dev/null | sed 's/.*vmlinuz-//') local -a file_list - mapfile -t file_list < <(find /var/cache/akmods -mindepth 3 2>/dev/null | grep -Fv -f <(echo "${excluded}")) + mapfile -t file_list < <(find /var/cache/akmods -mindepth 2 -type f -not -name .last.log 2>/dev/null | grep -Fv -f <(echo "${excluded}")) for one_file in "${file_list[@]}"; do if grep -q ".*\.rpm$" <<< "${one_file}" ; then if ! rpm -q "$(basename "${one_file%.rpm}")" >/dev/null ; then From ebb52e0d0a35591bf591295875461ca5354fb019 Mon Sep 17 00:00:00 2001 From: Thomas Deutschmann Date: Mon, 8 Dec 2025 23:20:58 +0100 Subject: [PATCH 78/79] kmodgenca: fallback to US when locale country code is missing rhbz#2416536 Fall back to "US" when `locale country_ab2` returns empty (as seen with LANG=C), preventing an empty countryName in the generated OpenSSL config. Fixes: rhbz#2416536 --- akmods-kmodgenca | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/akmods-kmodgenca b/akmods-kmodgenca index dafe69b..eab0882 100644 --- a/akmods-kmodgenca +++ b/akmods-kmodgenca @@ -433,6 +433,12 @@ function create_cacert_config() { # Set '-batch' argument. AUTOMATIC_BUILD_OPTION="-batch" + local cert_country_code=$(locale country_ab2) + if [[ -z ${cert_country_code} ]]; then + echo -e "${BOLD_YELLOW_TEXT}WARNING:${CLEAR_TEXT} COULD NOT DETECT COUNTRY CODE FROM LOCALE; USING FALLBACK VALUE: US" >&2 + cert_country_code=US + fi + # Utilise default values if 'AUTOMATIC_BUILD' is equal to '1'. # - Set OpenSSL field values. # - Comment default and min/max values. @@ -441,7 +447,7 @@ function create_cacert_config() { -e "s#\(emailAddress *= \).*#\1akmods@${cert_hostname}#" \ -e "s#\(localityName *= \).*#\1None#" \ -e "s#\(stateOrProvinceName *= \).*#\1None#" \ - -e "s#\(countryName *= \).*#\1$(locale country_ab2)#" \ + -e "s#\(countryName *= \).*#\1${cert_country_code}#" \ -e "s#\(commonName *= \).*#\1${KEYNAME}#" \ -e "s/^[^#]*_default *= /#&/" \ -e "s/^[^#]*_min/#&/" \ From f4104cf2817bc91ac85dd815f2ad64cabf99a07e Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Fri, 16 Jan 2026 03:32:40 +0000 Subject: [PATCH 79/79] Rebuilt for https://fedoraproject.org/wiki/Fedora_44_Mass_Rebuild