mirror of
https://github.com/systemd/systemd.git
synced 2024-12-22 17:35:35 +03:00
shared: split out crypt() specific helpers into its own .c/.h in src/shared/
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.
This commit is contained in:
parent
2ee4b118fa
commit
42f3b2f975
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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"
|
||||
|
75
src/shared/libcrypt-util.c
Normal file
75
src/shared/libcrypt-util.c
Normal file
@ -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
|
||||
}
|
20
src/shared/libcrypt-util.h
Normal file
20
src/shared/libcrypt-util.h
Normal file
@ -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);
|
@ -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,
|
||||
|
@ -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"
|
||||
|
Loading…
Reference in New Issue
Block a user