]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
shared: split out crypt() specific helpers into its own .c/.h in src/shared/
authorLennart Poettering <lennart@poettering.net>
Wed, 13 Nov 2019 22:13:42 +0000 (23:13 +0100)
committerLennart Poettering <lennart@poettering.net>
Wed, 15 Jan 2020 14:26:27 +0000 (15:26 +0100)
This way we can use libxcrypt specific functionality such as
crypt_gensalt() and thus take benefit of the newer algorithms libxcrypt
implements. (Also adds support for a new env var $SYSTEMD_CRYPT_PREFIX
which may be used to select the hash algorithm to use for libxcrypt.)

Also, let's move the weird crypt.h inclusion into libcrypt.h so that
there's a single place for it.

docs/ENVIRONMENT.md
src/basic/user-util.c
src/basic/user-util.h
src/firstboot/firstboot.c
src/shared/libcrypt-util.c [new file with mode: 0644]
src/shared/libcrypt-util.h [new file with mode: 0644]
src/shared/meson.build
src/test/test-user-util.c

index 9b1df6b59cb183a6a7145e808358d9eb71d78f41..fec40b1e9ca7528f796c2023137d120697e100c0 100644 (file)
@@ -73,6 +73,13 @@ All tools:
   appropriate path under /run. This variable is also set by the manager when
   RuntimeDirectory= is used, see systemd.exec(5).
 
+* `$SYSTEMD_CRYPT_PREFIX` — if set configures the hash method prefix to use for
+  UNIX crypt() when generating passwords. By default the system's "preferred
+  method" is used, but this can be overridden with this environment
+  variable. Takes a prefix such as `$6$` or `$y$`. (Note that this is only
+  honoured on systems built with libxcrypt and is ignored on systems using
+  glibc's original, internal crypt() implementation.)
+
 systemctl:
 
 * `$SYSTEMCTL_FORCE_BUS=1` — if set, do not connect to PID1's private D-Bus
index 571578c4e4946638217bf17e4b0bc306347796f1..68c6dd0da78a3a238bc1fbb201657ddbb45939d7 100644 (file)
@@ -945,40 +945,3 @@ int fgetsgent_sane(FILE *stream, struct sgrp **sg) {
         return !!s;
 }
 #endif
-
-int make_salt(char **ret) {
-        static const char table[] =
-                "abcdefghijklmnopqrstuvwxyz"
-                "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-                "0123456789"
-                "./";
-
-        uint8_t raw[16];
-        char *salt, *j;
-        size_t i;
-        int r;
-
-        /* This is a bit like crypt_gensalt_ra(), but doesn't require libcrypt, and doesn't do anything but
-         * SHA512, i.e. is legacy-free and minimizes our deps. */
-
-        assert_cc(sizeof(table) == 64U + 1U);
-
-        /* Insist on the best randomness by setting RANDOM_BLOCK, this is about keeping passwords secret after all. */
-        r = genuine_random_bytes(raw, sizeof(raw), RANDOM_BLOCK);
-        if (r < 0)
-                return r;
-
-        salt = new(char, 3+sizeof(raw)+1+1);
-        if (!salt)
-                return -ENOMEM;
-
-        /* We only bother with SHA512 hashed passwords, the rest is legacy, and we don't do legacy. */
-        j = stpcpy(salt, "$6$");
-        for (i = 0; i < sizeof(raw); i++)
-                j[i] = table[raw[i] & 63];
-        j[i++] = '$';
-        j[i] = 0;
-
-        *ret = salt;
-        return 0;
-}
index e11dd9b379c0ef20d70e32543f789fbf2176a46d..714e83082c9a15ee3b7d43e0ba65e83d9356bcf0 100644 (file)
@@ -137,6 +137,4 @@ int fgetsgent_sane(FILE *stream, struct sgrp **sg);
 int putsgent_sane(const struct sgrp *sg, FILE *stream);
 #endif
 
-int make_salt(char **ret);
-
 bool is_nologin_shell(const char *shell);
index 528e6452cf41eac5d3e769e3497b61d3c87c47c7..8001f90d57abbb6f7ba12d0277a53e7f0b89b72d 100644 (file)
@@ -4,19 +4,6 @@
 #include <getopt.h>
 #include <unistd.h>
 
-#if HAVE_CRYPT_H
-/* libxcrypt is a replacement for glibc's libcrypt, and libcrypt might be
- * removed from glibc at some point. As part of the removal, defines for
- * crypt(3) are dropped from unistd.h, and we must include crypt.h instead.
- *
- * Newer versions of glibc (v2.0+) already ship crypt.h with a definition
- * of crypt(3) as well, so we simply include it if it is present.  MariaDB,
- * MySQL, PostgreSQL, Perl and some other wide-spread packages do it the
- * same way since ages without any problems.
- */
-#  include <crypt.h>
-#endif
-
 #include "sd-id128.h"
 
 #include "alloc-util.h"
@@ -28,6 +15,7 @@
 #include "fs-util.h"
 #include "hostname-util.h"
 #include "kbd-util.h"
+#include "libcrypt-util.h"
 #include "locale-util.h"
 #include "main-func.h"
 #include "memory-util.h"
diff --git a/src/shared/libcrypt-util.c b/src/shared/libcrypt-util.c
new file mode 100644 (file)
index 0000000..b1a8168
--- /dev/null
@@ -0,0 +1,75 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+
+#include <errno.h>
+#include <stdlib.h>
+
+#include "alloc-util.h"
+#include "libcrypt-util.h"
+#include "log.h"
+#include "macro.h"
+#include "missing_stdlib.h"
+#include "random-util.h"
+#include "string-util.h"
+#include "strv.h"
+
+int make_salt(char **ret) {
+
+#ifdef XCRYPT_VERSION_MAJOR
+        const char *e;
+        char *salt;
+
+        /* If we have libxcrypt we default to the "preferred method" (i.e. usually yescrypt), and generate it
+         * with crypt_gensalt_ra(). */
+
+        e = secure_getenv("SYSTEMD_CRYPT_PREFIX");
+        if (!e)
+                e = crypt_preferred_method();
+
+        log_debug("Generating salt for hash prefix: %s", e);
+
+        salt = crypt_gensalt_ra(e, 0, NULL, 0);
+        if (!salt)
+                return -errno;
+
+        *ret = salt;
+        return 0;
+#else
+        /* If libxcrypt is not used, we use SHA512 and generate the salt on our own since crypt_gensalt_ra()
+         * is not available. */
+
+        static const char table[] =
+                "abcdefghijklmnopqrstuvwxyz"
+                "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+                "0123456789"
+                "./";
+
+        uint8_t raw[16];
+        char *salt, *j;
+        size_t i;
+        int r;
+
+        /* This is a bit like crypt_gensalt_ra(), but doesn't require libcrypt, and doesn't do anything but
+         * SHA512, i.e. is legacy-free and minimizes our deps. */
+
+        assert_cc(sizeof(table) == 64U + 1U);
+
+        /* Insist on the best randomness by setting RANDOM_BLOCK, this is about keeping passwords secret after all. */
+        r = genuine_random_bytes(raw, sizeof(raw), RANDOM_BLOCK);
+        if (r < 0)
+                return r;
+
+        salt = new(char, 3+sizeof(raw)+1+1);
+        if (!salt)
+                return -ENOMEM;
+
+        /* We only bother with SHA512 hashed passwords, the rest is legacy, and we don't do legacy. */
+        j = stpcpy(salt, "$6$");
+        for (i = 0; i < sizeof(raw); i++)
+                j[i] = table[raw[i] & 63];
+        j[i++] = '$';
+        j[i] = 0;
+
+        *ret = salt;
+        return 0;
+#endif
+}
diff --git a/src/shared/libcrypt-util.h b/src/shared/libcrypt-util.h
new file mode 100644 (file)
index 0000000..3da1ab5
--- /dev/null
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+#pragma once
+
+#if HAVE_CRYPT_H
+/* libxcrypt is a replacement for glibc's libcrypt, and libcrypt might be
+ * removed from glibc at some point. As part of the removal, defines for
+ * crypt(3) are dropped from unistd.h, and we must include crypt.h instead.
+ *
+ * Newer versions of glibc (v2.0+) already ship crypt.h with a definition
+ * of crypt(3) as well, so we simply include it if it is present.  MariaDB,
+ * MySQL, PostgreSQL, Perl and some other wide-spread packages do it the
+ * same way since ages without any problems.
+ */
+#include <crypt.h>
+#endif
+
+#include <stdbool.h>
+#include <stdlib.h>
+
+int make_salt(char **ret);
index 08aa480b6c8b551d465b819cdf91018a7735fc97..f4f5ebf3c432ef3575624f1d40da20037550a220 100644 (file)
@@ -106,6 +106,8 @@ shared_sources = files('''
         json-internal.h
         json.c
         json.h
+        libcrypt-util.c
+        libcrypt-util.h
         libmount-util.h
         linux/auto_dev-ioctl.h
         linux/bpf.h
@@ -279,6 +281,7 @@ libshared_deps = [threads,
                   libacl,
                   libblkid,
                   libcap,
+                  libcrypt,
                   libcryptsetup,
                   libgcrypt,
                   libidn,
index fde8336bf9b7a094773d10ec187691f9186d96a1..6bfe7dc7e174109ec8c9058750db983584fe5e9e 100644 (file)
@@ -2,6 +2,7 @@
 
 #include "alloc-util.h"
 #include "format-util.h"
+#include "libcrypt-util.h"
 #include "log.h"
 #include "macro.h"
 #include "memory-util.h"