]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
env-util: add unsetenv_erase() helper
authorLennart Poettering <lennart@poettering.net>
Mon, 16 Aug 2021 14:41:34 +0000 (16:41 +0200)
committerLennart Poettering <lennart@poettering.net>
Tue, 17 Aug 2021 11:17:44 +0000 (13:17 +0200)
Let's unify how we remove secrets from the env block.

src/basic/env-util.c
src/basic/env-util.h
src/cryptenroll/cryptenroll-password.c
src/cryptenroll/cryptenroll.c
src/cryptsetup/cryptsetup-fido2.c
src/home/homectl.c
src/shared/pkcs11-util.c
src/test/test-env-util.c

index cb4912564414e57d3f5ff6013157cf819e473fbd..b42ca50b2505ae81c01b79bdbc7040925c031532 100644 (file)
@@ -870,3 +870,20 @@ int getenv_path_list(const char *name, char ***ret_paths) {
         *ret_paths = TAKE_PTR(l);
         return 1;
 }
+
+int unsetenv_erase(const char *name) {
+        char *p;
+
+        assert(name);
+
+        p = getenv(name);
+        if (!p)
+                return 0;
+
+        string_erase(p);
+
+        if (unsetenv(name) < 0)
+                return -errno;
+
+        return 1;
+}
index bee284b1684245885f608d63f62430f849613faf..38bfc8a3f2c18df98393404835329bdca16f5664 100644 (file)
@@ -68,3 +68,5 @@ int setenv_systemd_exec_pid(bool update_only);
 /* Parses and does sanity checks on an environment variable containing
  * PATH-like colon-separated absolute paths */
 int getenv_path_list(const char *name, char ***ret_paths);
+
+int unsetenv_erase(const char *name);
index 0314831174be1ea6cb996b99d9ef7260f52cc78f..1775912d8e52711de35bf9df4d1cd4d909ff7fe0 100644 (file)
@@ -2,6 +2,7 @@
 
 #include "ask-password-api.h"
 #include "cryptenroll-password.h"
+#include "env-util.h"
 #include "escape.h"
 #include "memory-util.h"
 #include "pwquality-util.h"
@@ -27,8 +28,7 @@ int enroll_password(
                 if (!new_password)
                         return log_oom();
 
-                string_erase(e);
-                assert_se(unsetenv("NEWPASSWORD") == 0);
+                assert_se(unsetenv_erase("NEWPASSWORD") >= 0);
 
         } else {
                 _cleanup_free_ char *disk_path = NULL;
index f2e194e88c5e4479c85781972f4610a47ac81cbb..cf99aab96db410406a394293bed0dbd97d42bb26 100644 (file)
@@ -12,6 +12,7 @@
 #include "cryptenroll-wipe.h"
 #include "cryptenroll.h"
 #include "cryptsetup-util.h"
+#include "env-util.h"
 #include "escape.h"
 #include "libfido2-util.h"
 #include "main-func.h"
@@ -426,8 +427,7 @@ static int prepare_luks(
                 if (!password)
                         return log_oom();
 
-                string_erase(e);
-                assert_se(unsetenv("PASSWORD") >= 0);
+                assert_se(unsetenv_erase("PASSWORD") >= 0);
 
                 r = crypt_volume_key_get(
                                 cd,
index dfaded3cdb7afc7e59b472274f55c8ab9ceca1ae..74b6bff1aa0484e5f7d0ca92097607defbcfd80d 100644 (file)
@@ -2,6 +2,7 @@
 
 #include "ask-password-api.h"
 #include "cryptsetup-fido2.h"
+#include "env-util.h"
 #include "fileio.h"
 #include "hexdecoct.h"
 #include "json.h"
@@ -70,9 +71,7 @@ int acquire_fido2_key(
                 if (!pins)
                         return log_oom();
 
-                string_erase(e);
-                if (unsetenv("PIN") < 0)
-                        return log_error_errno(errno, "Failed to unset $PIN: %m");
+                assert_se(unsetenv_erase("PIN") >= 0);
         }
 
         for (;;) {
index a4c0a47ce56bebd60ace8355e3b54671543cef5f..66e1467d1a9179269b37f932910eead0f3f5ec5f 100644 (file)
@@ -215,9 +215,7 @@ static int acquire_existing_password(
                 if (r < 0)
                         return log_error_errno(r, "Failed to store password: %m");
 
-                string_erase(e);
-                assert_se(unsetenv("PASSWORD") == 0);
-
+                assert_se(unsetenv_erase("PASSWORD") >= 0);
                 return 1;
         }
 
@@ -273,9 +271,7 @@ static int acquire_token_pin(
                 if (r < 0)
                         return log_error_errno(r, "Failed to store token PIN: %m");
 
-                string_erase(e);
-                assert_se(unsetenv("PIN") == 0);
-
+                assert_se(unsetenv_erase("PIN") >= 0);
                 return 1;
         }
 
@@ -1097,8 +1093,7 @@ static int acquire_new_password(
                 if (r < 0)
                         return log_error_errno(r, "Failed to store password: %m");
 
-                string_erase(e);
-                assert_se(unsetenv("NEWPASSWORD") == 0);
+                assert_se(unsetenv_erase("NEWPASSWORD") >= 0);
 
                 if (ret)
                         *ret = TAKE_PTR(copy);
index 9fc577ca3cf1c7c4dd1f2fc2f262e6d71cc91181..ff3f245699849f0206fd7dc4d5cf2a58029888e3 100644 (file)
@@ -3,6 +3,7 @@
 #include <fcntl.h>
 
 #include "ask-password-api.h"
+#include "env-util.h"
 #include "escape.h"
 #include "fd-util.h"
 #include "format-table.h"
@@ -245,9 +246,7 @@ int pkcs11_token_login(
                         if (!passwords)
                                 return log_oom();
 
-                        string_erase(e);
-                        if (unsetenv("PIN") < 0)
-                                return log_error_errno(errno, "Failed to unset $PIN: %m");
+                        assert_se(unsetenv_erase("PIN") >= 0);
                 } else if (headless)
                         return log_error_errno(SYNTHETIC_ERRNO(ENOPKG), "PIN querying disabled via 'headless' option. Use the 'PIN' environment variable.");
                 else {
index c689d5590ee3fe48005d26022262908b57a458c7..0e4b832ba8727523f2bd1165e5a1ff1b75efe66c 100644 (file)
@@ -428,6 +428,52 @@ static void test_setenv_systemd_exec_pid(void) {
         assert_se(set_unset_env("SYSTEMD_EXEC_PID", saved, 1) >= 0);
 }
 
+static void test_unsetenv_erase(void) {
+        int r;
+
+        log_info("/* %s */", __func__);
+
+        r = safe_fork("(sd-unsetenverase)", FORK_DEATHSIG|FORK_LOG|FORK_WAIT, NULL);
+        if (r == 0) {
+                _cleanup_strv_free_ char **l = NULL;
+                char **e;
+
+                /* child */
+
+                assert_se(unsetenv_erase("thisenvvardefinitelywontexist") == 0);
+
+                l = strv_new("FOO=BAR", "QUUX=PIFF", "ONE=TWO", "A=B");
+                assert_se(strv_length(l) == 4);
+
+                environ = l;
+
+                STRV_FOREACH(e, environ) {
+                        _cleanup_free_ char *n = NULL;
+                        char *eq;
+
+                        eq = strchr(*e, '=');
+                        if (!eq)
+                                continue;
+
+                        n = strndup(*e, eq - *e);
+                        assert_se(n);
+
+                        assert_se(streq_ptr(getenv(n), eq + 1));
+                        assert_se(getenv(n) == eq + 1);
+                        assert_se(unsetenv_erase(n) > 0);
+                        assert_se(isempty(eq + 1));
+                        assert_se(!getenv(n));
+                }
+
+                environ = NULL;
+                l = strv_free(l);
+
+                _exit(EXIT_SUCCESS);
+        }
+
+        assert_se(r > 0);
+}
+
 int main(int argc, char *argv[]) {
         test_setup_logging(LOG_DEBUG);
 
@@ -451,6 +497,7 @@ int main(int argc, char *argv[]) {
         test_env_assignment_is_valid();
         test_putenv_dup();
         test_setenv_systemd_exec_pid();
+        test_unsetenv_erase();
 
         return 0;
 }