/* SPDX-License-Identifier: LGPL-2.1-or-later */

#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>
#else
#  include <unistd.h>
#endif

#include <errno.h>
#include <stdlib.h>

#include "alloc-util.h"
#include "errno-util.h"
#include "libcrypt-util.h"
#include "log.h"
#include "macro.h"
#include "memory-util.h"
#include "missing_stdlib.h"
#include "random-util.h"
#include "string-util.h"
#include "strv.h"

int make_salt(char **ret) {

#if HAVE_CRYPT_GENSALT_RA
        const char *e;
        char *salt;

        /* If we have crypt_gensalt_ra() we default to the "preferred method" (i.e. usually yescrypt).
         * crypt_gensalt_ra() is usually provided by libxcrypt. */

        e = secure_getenv("SYSTEMD_CRYPT_PREFIX");
        if (!e)
#if HAVE_CRYPT_PREFERRED_METHOD
                e = crypt_preferred_method();
#else
                e = "$6$";
#endif

        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 crypt_gensalt_ra() is not available, we use SHA512 and generate the salt on our own. */

        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);

        log_debug("Generating fallback salt for hash prefix: $6$");

        /* Insist on the best randomness by setting RANDOM_BLOCK, this is about keeping passwords secret after all. */
        r = crypto_random_bytes(raw, sizeof(raw));
        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
}

#if HAVE_CRYPT_RA
#  define CRYPT_RA_NAME "crypt_ra"
#else
#  define CRYPT_RA_NAME "crypt_r"

/* Provide a poor man's fallback that uses a fixed size buffer. */

static char* systemd_crypt_ra(const char *phrase, const char *setting, void **data, int *size) {
        assert(data);
        assert(size);

        /* We allocate the buffer because crypt(3) says: struct crypt_data may be quite large (32kB in this
         * implementation of libcrypt; over 128kB in some other implementations). This is large enough that
         * it may be unwise to allocate it on the stack. */

        if (!*data) {
                *data = new0(struct crypt_data, 1);
                if (!*data) {
                        errno = -ENOMEM;
                        return NULL;
                }

                *size = (int) (sizeof(struct crypt_data));
        }

        char *t = crypt_r(phrase, setting, *data);
        if (!t)
                return NULL;

        /* crypt_r may return a pointer to an invalid hashed password on error. Our callers expect NULL on
         * error, so let's just return that. */
        if (t[0] == '*')
                return NULL;

        return t;
}

#define crypt_ra systemd_crypt_ra

#endif

int hash_password_full(const char *password, void **cd_data, int *cd_size, char **ret) {
        _cleanup_free_ char *salt = NULL;
        _cleanup_(erase_and_freep) void *_cd_data = NULL;
        char *p;
        int r, _cd_size = 0;

        assert(!!cd_data == !!cd_size);

        r = make_salt(&salt);
        if (r < 0)
                return log_debug_errno(r, "Failed to generate salt: %m");

        errno = 0;
        p = crypt_ra(password, salt, cd_data ?: &_cd_data, cd_size ?: &_cd_size);
        if (!p)
                return log_debug_errno(errno_or_else(SYNTHETIC_ERRNO(EINVAL)),
                                       CRYPT_RA_NAME "() failed: %m");

        p = strdup(p);
        if (!p)
                return -ENOMEM;

        *ret = p;
        return 0;
}

bool looks_like_hashed_password(const char *s) {
        /* Returns false if the specified string is certainly not a hashed UNIX password. crypt(5) lists
         * various hashing methods. We only reject (return false) strings which are documented to have
         * different meanings.
         *
         * In particular, we allow locked passwords, i.e. strings starting with "!", including just "!",
         * i.e. the locked empty password. See also fc58c0c7bf7e4f525b916e3e5be0de2307fef04e.
         */
        if (!s)
                return false;

        s += strspn(s, "!"); /* Skip (possibly duplicated) locking prefix */

        return !STR_IN_SET(s, "x", "*");
}

int test_password_one(const char *hashed_password, const char *password) {
        _cleanup_(erase_and_freep) void *cd_data = NULL;
        int cd_size = 0;
        const char *k;

        errno = 0;
        k = crypt_ra(password, hashed_password, &cd_data, &cd_size);
        if (!k) {
                if (errno == ENOMEM)
                        return -ENOMEM;
                /* Unknown or unavailable hashing method or string too short */
                return 0;
        }

        return streq(k, hashed_password);
}

int test_password_many(char **hashed_password, const char *password) {
        int r;

        STRV_FOREACH(hpw, hashed_password) {
                r = test_password_one(*hpw, password);
                if (r < 0)
                        return r;
                if (r > 0)
                        return true;
        }

        return false;
}
