]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Add a helper function that does make_salt+crypt_r
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 8 Sep 2020 12:52:13 +0000 (14:52 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 15 Sep 2020 07:30:56 +0000 (09:30 +0200)
No functional change.

src/firstboot/firstboot.c
src/home/homectl-fido2.c
src/home/homectl-pkcs11.c
src/home/homectl-recovery-key.c
src/home/homework.c
src/home/user-record-util.c
src/shared/libcrypt-util.c
src/shared/libcrypt-util.h

index f8499a6ffd0ce42dee8b8c4acd011b7e5107339c..3109f9cdfcc214ca764c48146469e19683ae8177 100644 (file)
@@ -802,7 +802,7 @@ static int write_root_shadow(const char *shadow_path, const char *hashed_passwor
 
 static int process_root_args(void) {
         _cleanup_close_ int lock = -1;
-        struct crypt_data cd = {};
+        _cleanup_(erase_and_freep) char *_hashed_password = NULL;
         const char *password, *hashed_password;
         const char *etc_passwd, *etc_shadow;
         int r;
@@ -866,20 +866,13 @@ static int process_root_args(void) {
                 password = "x";
                 hashed_password = arg_root_password;
         } else if (arg_root_password) {
-                _cleanup_free_ char *salt = NULL;
-                /* hashed_password points inside cd after crypt_r returns so cd has function scope. */
+                r = hash_password(arg_root_password, &_hashed_password);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to hash password: %m");
 
                 password = "x";
+                hashed_password = _hashed_password;
 
-                r = make_salt(&salt);
-                if (r < 0)
-                        return log_error_errno(r, "Failed to get salt: %m");
-
-                errno = 0;
-                hashed_password = crypt_r(arg_root_password, salt, &cd);
-                if (!hashed_password)
-                        return log_error_errno(errno == 0 ? SYNTHETIC_ERRNO(EINVAL) : errno,
-                                        "Failed to encrypt password: %m");
         } else if (arg_delete_root_password)
                 password = hashed_password = "";
         else
index b7b2c1a3b5b3df7b1116564329f14994659fca71..b9092df18c5d628f5c2548936020bddd674f1804 100644 (file)
@@ -70,31 +70,23 @@ static int add_fido2_salt(
                 size_t secret_size) {
 
         _cleanup_(json_variant_unrefp) JsonVariant *l = NULL, *w = NULL, *e = NULL;
-        _cleanup_(erase_and_freep) char *base64_encoded = NULL;
-        _cleanup_free_ char *unix_salt = NULL;
-        struct crypt_data cd = {};
-        char *k;
+        _cleanup_(erase_and_freep) char *base64_encoded = NULL, *hashed = NULL;
         int r;
 
-        r = make_salt(&unix_salt);
-        if (r < 0)
-                return log_error_errno(r, "Failed to generate salt: %m");
-
         /* Before using UNIX hashing on the supplied key we base64 encode it, since crypt_r() and friends
          * expect a NUL terminated string, and we use a binary key */
         r = base64mem(secret, secret_size, &base64_encoded);
         if (r < 0)
                 return log_error_errno(r, "Failed to base64 encode secret key: %m");
 
-        errno = 0;
-        k = crypt_r(base64_encoded, unix_salt, &cd);
-        if (!k)
+        r = hash_password(base64_encoded, &hashed);
+        if (r < 0)
                 return log_error_errno(errno_or_else(EINVAL), "Failed to UNIX hash secret key: %m");
 
         r = json_build(&e, JSON_BUILD_OBJECT(
                                        JSON_BUILD_PAIR("credential", JSON_BUILD_BASE64(cid, cid_size)),
                                        JSON_BUILD_PAIR("salt", JSON_BUILD_BASE64(fido2_salt, fido2_salt_size)),
-                                       JSON_BUILD_PAIR("hashedPassword", JSON_BUILD_STRING(k))));
+                                       JSON_BUILD_PAIR("hashedPassword", JSON_BUILD_STRING(hashed))));
         if (r < 0)
                 return log_error_errno(r, "Failed to build FIDO2 salt JSON key object: %m");
 
index f4253ed7bf28d583b45420f89a6a49894caa256f..21c9b9a6a312eedeba0c80fa865063bd7127cd12 100644 (file)
@@ -134,10 +134,7 @@ static int add_pkcs11_encrypted_key(
                 const void *decrypted_key, size_t decrypted_key_size) {
 
         _cleanup_(json_variant_unrefp) JsonVariant *l = NULL, *w = NULL, *e = NULL;
-        _cleanup_(erase_and_freep) char *base64_encoded = NULL;
-        _cleanup_free_ char *salt = NULL;
-        struct crypt_data cd = {};
-        char *k;
+        _cleanup_(erase_and_freep) char *base64_encoded = NULL, *hashed = NULL;
         int r;
 
         assert(v);
@@ -147,25 +144,20 @@ static int add_pkcs11_encrypted_key(
         assert(decrypted_key);
         assert(decrypted_key_size > 0);
 
-        r = make_salt(&salt);
-        if (r < 0)
-                return log_error_errno(r, "Failed to generate salt: %m");
-
         /* Before using UNIX hashing on the supplied key we base64 encode it, since crypt_r() and friends
          * expect a NUL terminated string, and we use a binary key */
         r = base64mem(decrypted_key, decrypted_key_size, &base64_encoded);
         if (r < 0)
                 return log_error_errno(r, "Failed to base64 encode secret key: %m");
 
-        errno = 0;
-        k = crypt_r(base64_encoded, salt, &cd);
-        if (!k)
+        r = hash_password(base64_encoded, &hashed);
+        if (r < 0)
                 return log_error_errno(errno_or_else(EINVAL), "Failed to UNIX hash secret key: %m");
 
         r = json_build(&e, JSON_BUILD_OBJECT(
                                        JSON_BUILD_PAIR("uri", JSON_BUILD_STRING(uri)),
                                        JSON_BUILD_PAIR("data", JSON_BUILD_BASE64(encrypted_key, encrypted_key_size)),
-                                       JSON_BUILD_PAIR("hashedPassword", JSON_BUILD_STRING(k))));
+                                       JSON_BUILD_PAIR("hashedPassword", JSON_BUILD_STRING(hashed))));
         if (r < 0)
                 return log_error_errno(r, "Failed to build encrypted JSON key object: %m");
 
index 9d7f345f1ed4838653502625aed6d4f7e110f6d0..c63d3415f4bb3878e393a6297ef9fe2740772f1f 100644 (file)
@@ -183,9 +183,7 @@ static int print_qr_code(const char *secret) {
 }
 
 int identity_add_recovery_key(JsonVariant **v) {
-        _cleanup_(erase_and_freep) char *unix_salt = NULL, *password = NULL;
-        struct crypt_data cd = {};
-        char *k;
+        _cleanup_(erase_and_freep) char *password = NULL, *hashed = NULL;
         int r;
 
         assert(v);
@@ -196,17 +194,12 @@ int identity_add_recovery_key(JsonVariant **v) {
                 return r;
 
         /* Let's UNIX hash it */
-        r = make_salt(&unix_salt);
+        r = hash_password(password, &hashed);
         if (r < 0)
-                return log_error_errno(r, "Failed to generate salt: %m");
-
-        errno = 0;
-        k = crypt_r(password, unix_salt, &cd);
-        if (!k)
                 return log_error_errno(errno_or_else(EINVAL), "Failed to UNIX hash secret key: %m");
 
         /* Let's now add the "privileged" version of the recovery key */
-        r = add_privileged(v, k);
+        r = add_privileged(v, hashed);
         if (r < 0)
                 return r;
 
index 594c4a05bbf2ef2f2aa464f0c89920f22508600c..986ce2b3f09d04aa83f5a5db0d0d9feeaf23b54c 100644 (file)
@@ -17,6 +17,7 @@
 #include "homework-mount.h"
 #include "homework-pkcs11.h"
 #include "homework.h"
+#include "libcrypt-util.h"
 #include "main-func.h"
 #include "memory-util.h"
 #include "missing_magic.h"
index 0bbe44ce264826b18bea1946da7b3634a7809849..6928427730bcb11f7088241ed19f422e7ab909a3 100644 (file)
@@ -806,20 +806,13 @@ int user_record_make_hashed_password(UserRecord *h, char **secret, bool extend)
         }
 
         STRV_FOREACH(i, secret) {
-                _cleanup_free_ char *salt = NULL;
-                struct crypt_data cd = {};
-                char *k;
+                _cleanup_(erase_and_freep) char *hashed = NULL;
 
-                r = make_salt(&salt);
+                r = hash_password(*i, &hashed);
                 if (r < 0)
                         return r;
 
-                errno = 0;
-                k = crypt_r(*i, salt, &cd);
-                if (!k)
-                        return errno_or_else(EINVAL);
-
-                r = strv_extend(&np, k);
+                r = strv_consume(&np, TAKE_PTR(hashed));
                 if (r < 0)
                         return r;
         }
index bf6605508af4d05494fc403022d17d402691743c..d19bcf1d8abbf19ccceca02bda82002c32775498 100644 (file)
@@ -4,6 +4,7 @@
 #include <stdlib.h>
 
 #include "alloc-util.h"
+#include "errno-util.h"
 #include "libcrypt-util.h"
 #include "log.h"
 #include "macro.h"
@@ -74,6 +75,30 @@ int make_salt(char **ret) {
 #endif
 }
 
+int hash_password(const char *password, char **ret) {
+        _cleanup_free_ char *salt = NULL;
+        char *p;
+        struct crypt_data cd = {};
+        int r;
+
+        r = make_salt(&salt);
+        if (r < 0)
+                return log_debug_errno(r, "Failed to generate salt: %m");
+
+        errno = 0;
+        p = crypt_r(password, salt, &cd);
+        if (!p)
+                return log_debug_errno(errno_or_else(SYNTHETIC_ERRNO(EINVAL)),
+                                       "crypt_r() 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
index 8a860ceb0d853dccbcd6aa4445c79ca90d86f23a..b10be2f7d29e5ebd4d7b0ab019ae755639d45fce 100644 (file)
@@ -18,5 +18,5 @@
 #include <stdlib.h>
 
 int make_salt(char **ret);
-
+int hash_password(const char *password, char **ret);
 bool looks_like_hashed_password(const char *s);