From fca4faa773655caf5c0d2f6aa45433dbda0a63f4 Mon Sep 17 00:00:00 2001 From: Richard Penney Date: Sun, 25 Sep 2022 07:36:21 +0100 Subject: [PATCH] Reworked various locking/settling safeguards (rebase against 53e3552a) --- ChangeLog | 6 ++++++ INSTALL.md | 3 ++- Makefile.am | 4 +++- README.md | 20 +++++++++++++------- RELNOTES | 14 +++++++++++++- armour-gcry.c | 8 ++++++++ armour.c | 24 ++++++++++++++++++------ config.h.in | 3 +++ configure.ac | 4 ++-- cryptmount.spec | 2 +- dmutils.c | 25 +++++++++++-------------- po/cryptmount.pot | 24 ++++++++++++------------ po/de.po | 32 ++++++++++++++++++-------------- po/fr.po | 24 ++++++++++++------------ tables.c | 3 +++ testing/mudslinger.in | 15 ++++++++------- 16 files changed, 133 insertions(+), 78 deletions(-) diff --git a/ChangeLog b/ChangeLog index e6cd795..f65da4b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ ChangeLog for cryptmount (http://cryptmount.sourceforge.net) +01Oct22 - Improved udev settling schedule and filesystem syncs + Added partial support for compiling against libgcrypt-1.7 + +25Sep22 - Improved waiting schedule for inter-process status locks + Improved stability of tests against legacy cryptsetup + 11Sep22 - Revised installation instructions and top-level README 03Sep22 - *** cryptmount-6.0 released diff --git a/INSTALL.md b/INSTALL.md index fff513f..fa3846b 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -32,7 +32,8 @@ packages to be available, and should be driven by the "configure" script. If the configure script is missing, for example if working with a clone of cryptmount's [GitHub repository](https://github.com/rwpenney/cryptmount), -then you may need to set up autoconf (version 2.61 or later), and run +then you may need to set up [autoconf](https://www.gnu.org/software/autoconf/) +(version 2.61 or later), and run aclocal; autoconf; automake -a -c -i diff --git a/Makefile.am b/Makefile.am index cbd5072..c8143a5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -24,7 +24,7 @@ endif localedir=$(datadir)/locale AM_CPPFLAGS += -DLOCALEDIR=\"$(localedir)\" EXTRA_DIST = config.rpath mkinstalldirs cmtab.example \ - INSTALL.md README.md README.sshfs RELNOTES cryptmount.spec \ + INSTALL.md README.md README.sshfs RELNOTES cryptmount.spec \ debian/changelog debian/control \ debian/copyright debian/docs \ debian/rules debian/cryptmount.lintian-overrides \ @@ -89,6 +89,8 @@ cmtest: CFLAGS = -Wall -g -DTESTING -DCM_SRCDIR=\"${abs_srcdir}\" cmtest: ${bin_PROGRAMS} ${MAKE} -C testing autokeys mudslinger +test: cmtest + cd testing && sudo ./mudslinger .PHONY: depend depend: diff --git a/README.md b/README.md index 2f83774..a0d6b18 100644 --- a/README.md +++ b/README.md @@ -18,14 +18,20 @@ or raw disk partitions. ## Installation To build cryptmount from source, please follow the instructions in -the file 'INSTALL.md' in the same directory as this file. +the [INSTALL.md](https://github.com/rwpenney/cryptmount/blob/master/INSTALL.md) +file in the top directory of the source package. -cryptmount has been tested (using the ["mudslinger"](testing/mudslinger.in) script -on a variety of GNU/Linux platforms including: -Debian 11.0, Ubuntu 20.04, CentOS 7.6, ArchLinux etc. +cryptmount has been tested on a wide variety of GNU/Linux platforms including: +[ArchLinux](https://aur.archlinux.org/packages/cryptmount), +CentOS, [Debian](https://packages.debian.org/stable/cryptmount), Fedora, +[Gentoo](https://packages.gentoo.org/packages/sys-fs/cryptmount), +[Mageia](https://madb.mageia.org/package/show/source/1/application/0/release/cauldron/name/cryptmount), +[Ubuntu](https://packages.ubuntu.com/jammy/cryptmount) etc. For the most recent source-bundles of cryptmount, please see -[Sourceforge](http://www.sourceforge.net/projects/cryptmount). +[Sourceforge](http://www.sourceforge.net/projects/cryptmount), +or find the latest developer versions +on [GitHub](https://github.com/rwpenney/cryptmount). An encrypted filing system must initially be created by the superuser. A basic setup can be created interactively by running the `cryptmount-setup` @@ -34,8 +40,8 @@ use the [LUKS](https://en.wikipedia.org/wiki/Linux_Unified_Key_Setup) encryption format by default. More elaborate situations can be handled by manual editing of the -filesystem definition, typically in `/etc/cryptmount/cmtab` -or `/usr/local/etc/cryptmount/cmtab`. For example, an entry of the form: +filesystem definition, typically in `/etc/cryptmount/cmtab`. +For example, an entry of the form: ``` crypt { dev=/home/crypt.fs dir=/mnt/crypt diff --git a/RELNOTES b/RELNOTES index 0d691d0..b05a30b 100644 --- a/RELNOTES +++ b/RELNOTES @@ -1,6 +1,6 @@ Release notes for cryptmount-6.0 - RW Penney, September 2022 + RW Penney, October 2022 Introduction ============ @@ -26,6 +26,18 @@ control over the configuration and mounting of encrypted filesystems, especially within system start-up scripts. +Summary of new features in cryptmount-6.1 +========================================= + +This (beta) release is still under development + +It has been tested on the following systems: + + * Debian GNU/Linux 11.4 ("bullseye") (amd64) + + * Fedora 36 (x86_64) + + Summary of new features in cryptmount-6.0 ========================================= diff --git a/armour-gcry.c b/armour-gcry.c index 43f08f2..ac44224 100644 --- a/armour-gcry.c +++ b/armour-gcry.c @@ -84,7 +84,9 @@ static struct kmgcry_mode { { "ocb", GCRY_CIPHER_MODE_OCB }, { "ofb", GCRY_CIPHER_MODE_OFB }, { "poly1305", GCRY_CIPHER_MODE_POLY1305 }, +#if GCRYPT_VERSION_NUMBER >= 0x010800 { "xts", GCRY_CIPHER_MODE_XTS }, +#endif { NULL, GCRY_CIPHER_MODE_NONE } }; @@ -221,8 +223,10 @@ static int kmgcry_test_getalgos() GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CFB, GCRY_MD_RMD160 }, { "Camellia-128-cfb8", "sha256", GCRY_CIPHER_CAMELLIA128, GCRY_CIPHER_MODE_CFB8, GCRY_MD_SHA256 }, +#if GCRYPT_VERSION_NUMBER >= 0x010800 { "ChaCha20-xts", "blake2b_512", GCRY_CIPHER_CHACHA20, GCRY_CIPHER_MODE_XTS, GCRY_MD_BLAKE2B_512 }, +#endif { "DES-ofb", "md5", GCRY_CIPHER_DES, GCRY_CIPHER_MODE_OFB, GCRY_MD_MD5 }, { "twofish", "sha1", @@ -432,7 +436,11 @@ static int kmgcry_bind(bound_tgtdefn_t *bound, FILE *fp_key) } if (keyinfo->cipheralg == NULL) { +#if GCRYPT_VERSION_NUMBER >= 0x010800 keyinfo->cipheralg = cm_strdup("aes256-xts"); +#else + keyinfo->cipheralg = cm_strdup("aes256-cbc"); +#endif } } diff --git a/armour.c b/armour.c index b5ac839..bf4d391 100644 --- a/armour.c +++ b/armour.c @@ -400,6 +400,15 @@ int cm_put_key(bound_tgtdefn_t *boundtgt, const km_pw_context_t *pw_ctxt, eflag = boundtgt->keymgr->put_key(boundtgt, pw_ctxt, key, keylen, fp_key); + if (fp_key != NULL) { + int fd = fileno(fp_key); +#if HAVE_SYNCFS + syncfs(fd); +#else + fsync(fd); +#endif + } + return eflag; } @@ -794,17 +803,19 @@ static const char *cm_lock_filename = "_cryptmount_lock_"; int cm_mutex_lock(void) /** Try to acquire lock on configuration directory (via symlink marker) */ { char *fname=NULL, ident[64]; - int tries=10, eflag=ERR_BADMUTEX; + int eflag=ERR_BADMUTEX; #if HAVE_NANOSLEEP - int ticks; + int delay_ms; + unsigned dither = ((size_t)&fname % 250) + 1; struct timespec delay; #endif + const unsigned MAX_ATTEMPTS = 10; (void)cm_path(&fname, CM_SYSRUN_PFX, cm_lock_filename); snprintf(ident, sizeof(ident), "%u-%u", (unsigned)getpid(), (unsigned)getuid()); - while (tries-->0) { + for (unsigned attempt=0; attempt\n" "Language-Team: LANGUAGE \n" @@ -17,7 +17,7 @@ msgstr "" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" -#: armour.c:154 armour-builtin.c:300 armour-gcry.c:562 armour-gcry.c:718 +#: armour.c:154 armour-builtin.c:300 armour-gcry.c:570 armour-gcry.c:726 #, c-format msgid "Key-extraction failed for \"%s\"\n" msgstr "" @@ -42,52 +42,52 @@ msgstr "" msgid "Missing output keyfile for target \"%s\"\n" msgstr "" -#: armour.c:780 +#: armour.c:789 #, c-format msgid "Specification for target \"%s\" contains non-absolute pathname\n" msgstr "" -#: armour-builtin.c:282 armour-gcry.c:544 armour-gcry.c:699 +#: armour-builtin.c:282 armour-gcry.c:552 armour-gcry.c:707 #, c-format msgid "Password mismatch when extracting key\n" msgstr "" -#: armour-builtin.c:398 armour-gcry.c:623 armour-gcry.c:777 +#: armour-builtin.c:398 armour-gcry.c:631 armour-gcry.c:785 #, c-format msgid "Failed to create new key file\n" msgstr "" -#: armour-gcry.c:175 +#: armour-gcry.c:177 #, c-format msgid "Couldn't find libgcrypt cipher \"%s\"\n" msgstr "" -#: armour-gcry.c:184 +#: armour-gcry.c:186 #, c-format msgid "Couldn't find libgcrypt cipher mode \"%s\" - using fallback\n" msgstr "" -#: armour-gcry.c:190 +#: armour-gcry.c:192 #, c-format msgid "Couldn't find libgcrypt digest \"%s\"\n" msgstr "" -#: armour-gcry.c:505 +#: armour-gcry.c:513 #, c-format msgid "Bad keyfile format (libgcrypt)\n" msgstr "" -#: armour-gcry.c:548 +#: armour-gcry.c:556 #, c-format msgid "Checksum mismatch in keyfile (gcry, %x != %x)\n" msgstr "" -#: armour-gcry.c:664 +#: armour-gcry.c:672 #, c-format msgid "Bad keyfile format (openssl-compat)\n" msgstr "" -#: armour-gcry.c:703 +#: armour-gcry.c:711 #, c-format msgid "Checksum mismatch in keyfile (openssl-compat, ofs=%u,idx=%u)\n" msgstr "" diff --git a/po/de.po b/po/de.po index 81cddf8..93babc7 100644 --- a/po/de.po +++ b/po/de.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: cryptmount 6.0-1\n" "Report-Msgid-Bugs-To: rwpenney@users.sourceforge.net\n" -"POT-Creation-Date: 2022-09-03 09:39+0100\n" +"POT-Creation-Date: 2022-10-01 12:52+0100\n" "PO-Revision-Date: 2022-09-11 20:18+0200\n" "Last-Translator: Helge Kreutzmann \n" "Language-Team: German \n" @@ -16,7 +16,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: armour.c:154 armour-builtin.c:300 armour-gcry.c:562 armour-gcry.c:718 +#: armour.c:154 armour-builtin.c:300 armour-gcry.c:570 armour-gcry.c:726 #, c-format msgid "Key-extraction failed for \"%s\"\n" msgstr "Auslesen des Schlüssels für »%s« schlug fehl.\n" @@ -41,53 +41,55 @@ msgstr "Schlüsseldatei für Ziel »%s« fehlt.\n" msgid "Missing output keyfile for target \"%s\"\n" msgstr "Schlüsselausgabedatei für Ziel »%s« fehlt.\n" -#: armour.c:780 +#: armour.c:789 #, c-format msgid "Specification for target \"%s\" contains non-absolute pathname\n" msgstr "Die Zielangabe für »%s« enthält eine nicht-absolute Pfadangabe.\n" -#: armour-builtin.c:282 armour-gcry.c:544 armour-gcry.c:699 +#: armour-builtin.c:282 armour-gcry.c:552 armour-gcry.c:707 #, c-format msgid "Password mismatch when extracting key\n" msgstr "Fehlerhaftes Passwort während des Auslesens des Schlüssels.\n" -#: armour-builtin.c:398 armour-gcry.c:623 armour-gcry.c:777 +#: armour-builtin.c:398 armour-gcry.c:631 armour-gcry.c:785 #, c-format msgid "Failed to create new key file\n" msgstr "Erstellen einer neuen Schlüsseldatei schlug fehl.\n" -#: armour-gcry.c:175 +#: armour-gcry.c:177 #, c-format msgid "Couldn't find libgcrypt cipher \"%s\"\n" msgstr "Konnte libgcrypt-Chiffre »%s« nicht finden.\n" -#: armour-gcry.c:184 +#: armour-gcry.c:186 #, c-format msgid "Couldn't find libgcrypt cipher mode \"%s\" - using fallback\n" -msgstr "Konnte libgcrypt-Chiffrenmodus »%s« nicht finden - Rückfalloption wird verwandt\n" +msgstr "" +"Konnte libgcrypt-Chiffrenmodus »%s« nicht finden - Rückfalloption wird " +"verwandt\n" -#: armour-gcry.c:190 +#: armour-gcry.c:192 #, c-format msgid "Couldn't find libgcrypt digest \"%s\"\n" msgstr "Konnte libgcrypt-Hash »%s« nicht finden.\n" -#: armour-gcry.c:505 +#: armour-gcry.c:513 #, c-format msgid "Bad keyfile format (libgcrypt)\n" msgstr "Falsches Schlüsseldateiformat (libgcrypt).\n" -#: armour-gcry.c:548 +#: armour-gcry.c:556 #, c-format msgid "Checksum mismatch in keyfile (gcry, %x != %x)\n" msgstr "" "Nicht übereinstimmende Prüfsumme in der Schlüsseldatei (gcry, %x != %x).\n" -#: armour-gcry.c:664 +#: armour-gcry.c:672 #, c-format msgid "Bad keyfile format (openssl-compat)\n" msgstr "Falsches Schlüsseldateiformat (openssl-compat).\n" -#: armour-gcry.c:703 +#: armour-gcry.c:711 #, c-format msgid "Checksum mismatch in keyfile (openssl-compat, ofs=%u,idx=%u)\n" msgstr "" @@ -488,7 +490,9 @@ msgstr "" #: sysinit/setupscript.sh.in:64 #, sh-format msgid "No LUKS support available - using built-in key manager" -msgstr "Keine LUKS-Unterstützung verfügbar - eingebauter Schlüsselverwalter wird verwandt" +msgstr "" +"Keine LUKS-Unterstützung verfügbar - eingebauter Schlüsselverwalter wird " +"verwandt" #: sysinit/setupscript.sh.in:123 #, sh-format diff --git a/po/fr.po b/po/fr.po index 467f272..497294f 100644 --- a/po/fr.po +++ b/po/fr.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: cryptmount 4.0-1\n" "Report-Msgid-Bugs-To: rwpenney@users.sourceforge.net\n" -"POT-Creation-Date: 2022-09-17 09:43+0100\n" +"POT-Creation-Date: 2022-10-01 12:52+0100\n" "PO-Revision-Date: 2006-04-21 07:51+0100\n" "Last-Translator: RW Penney \n" "Language-Team: French \n" @@ -16,7 +16,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: armour.c:154 armour-builtin.c:300 armour-gcry.c:562 armour-gcry.c:718 +#: armour.c:154 armour-builtin.c:300 armour-gcry.c:570 armour-gcry.c:726 #, c-format msgid "Key-extraction failed for \"%s\"\n" msgstr "Extraction de la clef pour \"%s\" a echouée\n" @@ -41,52 +41,52 @@ msgstr "Pas de fichier-clef pour la cible \"%s\"\n" msgid "Missing output keyfile for target \"%s\"\n" msgstr "Pas de fichier-clef pour la cible \"%s\"\n" -#: armour.c:780 +#: armour.c:789 #, c-format msgid "Specification for target \"%s\" contains non-absolute pathname\n" msgstr "" -#: armour-builtin.c:282 armour-gcry.c:544 armour-gcry.c:699 +#: armour-builtin.c:282 armour-gcry.c:552 armour-gcry.c:707 #, c-format msgid "Password mismatch when extracting key\n" msgstr "Mot de passe n'est pas verifié\n" -#: armour-builtin.c:398 armour-gcry.c:623 armour-gcry.c:777 +#: armour-builtin.c:398 armour-gcry.c:631 armour-gcry.c:785 #, c-format msgid "Failed to create new key file\n" msgstr "Génération de nouvelle clef a echouée\n" -#: armour-gcry.c:175 +#: armour-gcry.c:177 #, c-format msgid "Couldn't find libgcrypt cipher \"%s\"\n" msgstr "Chiffre \"%s\" n'est pas reconnu dans libgcrypt\n" -#: armour-gcry.c:184 +#: armour-gcry.c:186 #, c-format msgid "Couldn't find libgcrypt cipher mode \"%s\" - using fallback\n" msgstr "Mode de chiffrage \"%s\" n'est pas reconnu dans libgcrypt\n" -#: armour-gcry.c:190 +#: armour-gcry.c:192 #, c-format msgid "Couldn't find libgcrypt digest \"%s\"\n" msgstr "Hash \"%s\" n'est pas reconnu dans libgcrypt\n" -#: armour-gcry.c:505 +#: armour-gcry.c:513 #, c-format msgid "Bad keyfile format (libgcrypt)\n" msgstr "Mauvais fichier-clef (libcrypt)\n" -#: armour-gcry.c:548 +#: armour-gcry.c:556 #, c-format msgid "Checksum mismatch in keyfile (gcry, %x != %x)\n" msgstr "Mauvais fichier-clef (gcry, %x != %x)\n" -#: armour-gcry.c:664 +#: armour-gcry.c:672 #, c-format msgid "Bad keyfile format (openssl-compat)\n" msgstr "Mauvais fichier-clef (openssl-compat)\n" -#: armour-gcry.c:703 +#: armour-gcry.c:711 #, c-format msgid "Checksum mismatch in keyfile (openssl-compat, ofs=%u,idx=%u)\n" msgstr "Mauvais fichier-clef (openssl-compat, ofs=%u,idx=%u)\n" diff --git a/tables.c b/tables.c index 77fee7e..2410145 100644 --- a/tables.c +++ b/tables.c @@ -814,6 +814,9 @@ void statfile_write(struct statfile *sf, const tgtstat_t *stat) void statfile_close(struct statfile *sf) { +#if HAVE_SYNCFS + syncfs(fileno(sf->fp)); +#endif fclose(sf->fp); free((void*)sf); } diff --git a/testing/mudslinger.in b/testing/mudslinger.in index 09e3f63..d5e78d4 100755 --- a/testing/mudslinger.in +++ b/testing/mudslinger.in @@ -687,7 +687,7 @@ EOF function test_cipher_algs() { # Test usability of different encryption algorithms - if test_start "cipher-algorithm availability"; then true; else return; fi + if test_start "cipher algorithm availability"; then true; else return; fi for CipherLen in aes,32 blowfish,48 twofish,32 serpent,12 do tupelize $CipherLen cipher len @@ -770,7 +770,7 @@ EOF function test_ssl_algs() { # Test usability of OpenSSL key & hashing algorithms - if test_start "OpenSSL-algorithm availability"; then true; else return; fi + if test_start "OpenSSL algorithm availability"; then true; else return; fi if ${CM} --key-managers 2>/dev/null | grep -q openssl; then true; else test_fail "No OpenSSL support"; return; fi for keycipher in aes-128-ecb aes-256-cbc camellia-128-cbc; do # Beware cfb*, ofb modes seem incompatible for unknown reasons @@ -808,7 +808,7 @@ EOF function test_gcry_algs() { # Test usability of libgcrypt key & hashing algorithms - if test_start "libgcrypt-algorithm availability"; then true; else return; fi + if test_start "libgcrypt algorithm availability"; then true; else return; fi if ${CM} --key-managers 2>/dev/null | grep -q -w libgcrypt; then true; else test_fail "No libgcrypt support"; return; fi for keycipher in aes192 blowfish cast5-ecb camellia-256-xts do @@ -848,7 +848,7 @@ EOF function test_gcryossl() { # Test usability of libgcrypt OpenSSL-compatibility layer - if test_start "libgcrypt OpenSSL-emulator"; then true; else return; fi + if test_start "libgcrypt OpenSSL emulator"; then true; else return; fi if ${CM} --key-managers 2>/dev/null | grep -q -w openssl-compat; then true; else test_fail "No openssl-compat support"; return; fi configs="aes-128-cbc:md5:aes-cbc:md5 \ aes-192-ecb:sha224:aes192-ecb:sha224 \ @@ -1254,7 +1254,8 @@ function test_cryptsetup_compat() { bs=16k count=16 2>/dev/null mke2fs -q -j /dev/mapper/cstarget${idx} wait_udev - cryptsetup remove cstarget${idx} + cryptsetup remove cstarget${idx} 2>&3 + wait_udev else test_fail "cryptsetup creation"; return fi @@ -1353,7 +1354,7 @@ EOF sync; wait_udev if ${SU_p} ${USER1} -c "${CM} --config-dir ${TMPDIR} --unmount target${idx}" 2>&3; then true; else test_fail "unmount"; return; fi if ${CM} --config-dir ${TMPDIR} --newpassword "${PASSWD}" --generate-key 16 target${idx} 2>&3; then test_fail "re-formatting"; fi - wait_udev + sync; wait_udev done rm ${TMPDIR}/keymat0 ${TMPDIR}/keymat test_pass @@ -1407,7 +1408,7 @@ EOF # Check that re-formatting is blocked: if ${CM} --config-dir ${TMPDIR} --newpassword "${PASSWD}" --generate-key 16 target${idx} 2>&3; then test_fail "re-formatting"; fi - wait_udev + sync; wait_udev done rm ${TMPDIR}/keymat test_pass