From 5ff8b590fc80a1c6a77f09387f33502b07761b9e Mon Sep 17 00:00:00 2001 From: Vladislav Nepogodin Date: Wed, 26 Jun 2024 21:14:24 +0400 Subject: [PATCH] =?UTF-8?q?=F0=9F=A7=B9=20move=20luks=20into=20gucc?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gucc/CMakeLists.txt | 1 + gucc/include/gucc/luks.hpp | 14 ++++++++++++++ gucc/meson.build | 1 + gucc/src/luks.cpp | 24 ++++++++++++++++++++++++ src/crypto.cpp | 21 ++++++++++++++++----- src/utils.cpp | 18 ++++++++++-------- 6 files changed, 66 insertions(+), 13 deletions(-) create mode 100644 gucc/include/gucc/luks.hpp create mode 100644 gucc/src/luks.cpp diff --git a/gucc/CMakeLists.txt b/gucc/CMakeLists.txt index 04602c5..8a581a0 100644 --- a/gucc/CMakeLists.txt +++ b/gucc/CMakeLists.txt @@ -16,6 +16,7 @@ add_library(${PROJECT_NAME} SHARED src/cpu.cpp include/gucc/cpu.hpp src/pacmanconf_repo.cpp include/gucc/pacmanconf_repo.hpp src/initcpio.cpp include/gucc/initcpio.hpp + src/luks.cpp include/gucc/luks.hpp #src/chwd_profiles.cpp src/chwd_profiles.hpp #src/disk.cpp src/disk.hpp ) diff --git a/gucc/include/gucc/luks.hpp b/gucc/include/gucc/luks.hpp new file mode 100644 index 0000000..3e871ff --- /dev/null +++ b/gucc/include/gucc/luks.hpp @@ -0,0 +1,14 @@ +#ifndef LUKS_HPP +#define LUKS_HPP + +#include // for string_view + +namespace gucc::crypto { + +auto luks1_open(std::string_view luks_pass, std::string_view partition, std::string_view luks_name) noexcept -> bool; +auto luks1_format(std::string_view luks_pass, std::string_view partition, std::string_view additional_flags = {}) noexcept -> bool; +auto luks1_add_key(std::string_view dest_file, std::string_view partition, std::string_view additional_flags = {}) noexcept -> bool; + +} // namespace gucc::crypto + +#endif // LUKS_HPP diff --git a/gucc/meson.build b/gucc/meson.build index 8c71ab4..e227bfa 100644 --- a/gucc/meson.build +++ b/gucc/meson.build @@ -6,6 +6,7 @@ gucc_lib = library('gucc', 'src/cpu.cpp', 'src/pacmanconf_repo.cpp', 'src/initcpio.cpp', + 'src/luks.cpp', ], include_directories : [include_directories('include')], dependencies: deps diff --git a/gucc/src/luks.cpp b/gucc/src/luks.cpp new file mode 100644 index 0000000..5f83182 --- /dev/null +++ b/gucc/src/luks.cpp @@ -0,0 +1,24 @@ +#include "gucc/luks.hpp" +#include "gucc/io_utils.hpp" + +#include +#include + +namespace gucc::crypto { + +auto luks1_open(std::string_view luks_pass, std::string_view partition, std::string_view luks_name) noexcept -> bool { + auto cmd = fmt::format(FMT_COMPILE("echo \"{}\" | cryptsetup open --type luks1 {} {} &>/dev/null"), luks_pass, partition, luks_name); + return utils::exec(cmd, true) == "0"; +} + +auto luks1_format(std::string_view luks_pass, std::string_view partition, std::string_view additional_flags) noexcept -> bool { + auto cmd = fmt::format(FMT_COMPILE("echo \"{}\" | cryptsetup -q {} --type luks1 luksFormat {} &>/dev/null"), luks_pass, additional_flags, partition); + return utils::exec(cmd, true) == "0"; +} + +auto luks1_add_key(std::string_view dest_file, std::string_view partition, std::string_view additional_flags) noexcept -> bool { + auto cmd = fmt::format(FMT_COMPILE("cryptsetup -q {} luksAddKey {} {} &>/dev/null"), additional_flags, partition, dest_file); + return utils::exec(cmd, true) == "0"; +} + +} // namespace gucc::crypto diff --git a/src/crypto.cpp b/src/crypto.cpp index f91efac..d42dfbe 100644 --- a/src/crypto.cpp +++ b/src/crypto.cpp @@ -5,6 +5,7 @@ // import gucc #include "gucc/io_utils.hpp" +#include "gucc/luks.hpp" #include "gucc/string_utils.hpp" #include @@ -112,7 +113,11 @@ bool luks_open() noexcept { // show the error detail::infobox_widget("\nPlease wait...\n"); #ifdef NDEVENV - detail::follow_process_log_widget({"/bin/sh", "-c", fmt::format(FMT_COMPILE("echo \"{}\" | cryptsetup open --type luks {} {}"), luks_password, partition, luks_root_name)}); + if (!gucc::crypto::luks1_open(luks_password, partition, luks_root_name)) { + spdlog::error("Failed to open luks1 partition {} with name {}", partition, luks_root_name); + detail::msgbox_widget("\nFailed to open luks1 partition\n"); + return false; + } #endif const auto& devlist = gucc::utils::exec(fmt::format(FMT_COMPILE("lsblk -o NAME,TYPE,FSTYPE,SIZE,MOUNTPOINT {} | grep \"crypt\\|NAME\\|MODEL\\|TYPE\\|FSTYPE\\|SIZE\""), partition)); @@ -160,15 +165,21 @@ void luks_encrypt([[maybe_unused]] const std::string_view& command) noexcept { const auto& luks_root_name = std::get(config_data["LUKS_ROOT_NAME"]); const auto& luks_password = std::get(config_data["PASSWD"]); - detail::follow_process_log_widget({"/bin/sh", "-c", fmt::format(FMT_COMPILE("echo \"{}\" | cryptsetup -q {} {}"), luks_password, command, partition)}); + if (!gucc::crypto::luks1_format(luks_password, partition, command)) { + spdlog::error("Failed to format luks1 partition {} with additional flags {}", partition, command); + detail::msgbox_widget("\nFailed to format luks1 partition\n"); + } // Now open the encrypted partition or LV - detail::follow_process_log_widget({"/bin/sh", "-c", fmt::format(FMT_COMPILE("echo \"{}\" | cryptsetup open {} {}"), luks_password, partition, luks_root_name)}); + if (!gucc::crypto::luks1_open(luks_password, partition, luks_root_name)) { + spdlog::error("Failed to open luks1 partition {} with name {}", partition, luks_root_name); + detail::msgbox_widget("\nFailed to open luks1 partition\n"); + } #endif } void luks_default() noexcept { - tui::luks_encrypt("--type luks1 luksFormat"); + tui::luks_encrypt(""); } bool luks_key_define() noexcept { @@ -183,7 +194,7 @@ bool luks_key_define() noexcept { } void luks_express() noexcept { - tui::luks_encrypt("--pbkdf-force-iterations 200000 --type luks1 luksFormat"); + tui::luks_encrypt("--pbkdf-force-iterations 200000"); } void luks_show() noexcept { diff --git a/src/utils.cpp b/src/utils.cpp index 41a0361..db0e66e 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -10,6 +10,7 @@ #include "gucc/file_utils.hpp" #include "gucc/initcpio.hpp" #include "gucc/io_utils.hpp" +#include "gucc/luks.hpp" #include "gucc/pacmanconf_repo.hpp" #include "gucc/string_utils.hpp" @@ -2031,25 +2032,26 @@ void setup_luks_keyfile() noexcept { // Add keyfile to luks const auto& root_name = gucc::utils::exec("mount | awk '/\\/mnt / {print $1}' | sed s~/dev/mapper/~~g | sed s~/dev/~~g"); const auto& root_part = gucc::utils::exec(fmt::format(FMT_COMPILE("lsblk -i | tac | sed -r 's/^[^[:alnum:]]+//' | sed -n -e \"/{}/,/part/p\" | {} | tr -cd '[:alnum:]'"), root_name, "awk '/part/ {print $1}'")); - const auto& number_of_lukskeys = utils::to_int(gucc::utils::exec(fmt::format(FMT_COMPILE("cryptsetup luksDump /dev/\"{}\" | grep \"ENABLED\" | wc -l"), root_part))); + const auto& partition = fmt::format(FMT_COMPILE("/dev/{}"), root_part); + const auto& number_of_lukskeys = utils::to_int(gucc::utils::exec(fmt::format(FMT_COMPILE("cryptsetup luksDump \"{}\" | grep \"ENABLED\" | wc -l"), partition))); if (number_of_lukskeys < 4) { // Create a keyfile #ifdef NDEVENV - if (!fs::exists("/mnt/crypto_keyfile.bin")) { + const std::string_view keyfile_path{"/mnt/crypto_keyfile.bin"}; + if (!fs::exists(keyfile_path)) { const auto& ret_status = gucc::utils::exec("dd bs=512 count=4 if=/dev/urandom of=/mnt/crypto_keyfile.bin", true); /* clang-format off */ if (ret_status == "0") { spdlog::info("Generating a keyfile"); } /* clang-format on */ } - gucc::utils::exec("chmod 000 /mnt/crypto_keyfile.bin"); + gucc::utils::exec("chmod 600 /mnt/crypto_keyfile.bin"); spdlog::info("Adding the keyfile to the LUKS configuration"); - auto ret_status = gucc::utils::exec(fmt::format(FMT_COMPILE("cryptsetup --pbkdf-force-iterations 200000 luksAddKey /dev/\"{}\" /mnt/crypto_keyfile.bin"), root_part), true); - /* clang-format off */ - if (ret_status != "0") { spdlog::info("Something went wrong with adding the LUKS key. Is /dev/{} the right partition?", root_part); } - /* clang-format on */ + if (!gucc::crypto::luks1_add_key(keyfile_path, partition, "--pbkdf-force-iterations 200000")) { + spdlog::error("Something went wrong with adding the LUKS key. Is {} the right partition?", partition); + } // Add keyfile to initcpio - ret_status = gucc::utils::exec("grep -q '/crypto_keyfile.bin' /mnt/etc/mkinitcpio.conf || sed -i '/FILES/ s~)~/crypto_keyfile.bin)~' /mnt/etc/mkinitcpio.conf", true); + auto ret_status = gucc::utils::exec("grep -q '/crypto_keyfile.bin' /mnt/etc/mkinitcpio.conf || sed -i '/FILES/ s~)~/crypto_keyfile.bin)~' /mnt/etc/mkinitcpio.conf", true); /* clang-format off */ if (ret_status == "0") { spdlog::info("Adding keyfile to the initcpio"); } /* clang-format on */