]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/shared/creds-util.c
tree-wide: use CLEANUP_ERASE() at various places
[thirdparty/systemd.git] / src / shared / creds-util.c
index 9f4d0832abf480efc68b00816d362c41d5307d9a..2ee62cd404050afe5cff4fc13be841348373be26 100644 (file)
@@ -86,6 +86,56 @@ int read_credential(const char *name, void **ret, size_t *ret_size) {
                         (char**) ret, ret_size);
 }
 
+int read_credential_strings_many_internal(
+                const char *first_name, char **first_value,
+                ...) {
+
+        _cleanup_free_ void *b = NULL;
+        int r, ret = 0;
+
+        /* Reads a bunch of credentials into the specified buffers. If the specified buffers are already
+         * non-NULL frees them if a credential is found. Only supports string-based credentials
+         * (i.e. refuses embedded NUL bytes) */
+
+        if (!first_name)
+                return 0;
+
+        r = read_credential(first_name, &b, NULL);
+        if (r == -ENXIO) /* no creds passed at all? propagate this */
+                return r;
+        if (r < 0)
+                ret = r;
+        else
+                free_and_replace(*first_value, b);
+
+        va_list ap;
+        va_start(ap, first_value);
+
+        for (;;) {
+                _cleanup_free_ void *bb = NULL;
+                const char *name;
+                char **value;
+
+                name = va_arg(ap, const char *);
+                if (!name)
+                        break;
+
+                value = va_arg(ap, char **);
+                if (*value)
+                        continue;
+
+                r = read_credential(name, &bb, NULL);
+                if (r < 0) {
+                        if (ret >= 0)
+                                ret = r;
+                } else
+                        free_and_replace(*value, bb);
+        }
+
+        va_end(ap);
+        return ret;
+}
+
 int get_credential_user_password(const char *username, char **ret_password, bool *ret_is_hashed) {
         _cleanup_(erase_and_freep) char *creds_password = NULL;
         _cleanup_free_ char *cn = NULL;
@@ -165,7 +215,6 @@ static int make_credential_host_secret(
                 void **ret_data,
                 size_t *ret_size) {
 
-        struct credential_host_secret_format buf;
         _cleanup_free_ char *t = NULL;
         _cleanup_close_ int fd = -EBADF;
         int r;
@@ -189,21 +238,23 @@ static int make_credential_host_secret(
         if (r < 0)
                 log_debug_errno(r, "Failed to set file attributes for secrets file, ignoring: %m");
 
-        buf = (struct credential_host_secret_format) {
+        struct credential_host_secret_format buf = {
                 .machine_id = machine_id,
         };
 
+        CLEANUP_ERASE(buf);
+
         r = crypto_random_bytes(buf.data, sizeof(buf.data));
         if (r < 0)
-                goto finish;
+                goto fail;
 
         r = loop_write(fd, &buf, sizeof(buf), false);
         if (r < 0)
-                goto finish;
+                goto fail;
 
         if (fsync(fd) < 0) {
                 r = -errno;
-                goto finish;
+                goto fail;
         }
 
         warn_not_encrypted(fd, flags, dirname, fn);
@@ -211,17 +262,17 @@ static int make_credential_host_secret(
         if (t) {
                 r = rename_noreplace(dfd, t, dfd, fn);
                 if (r < 0)
-                        goto finish;
+                        goto fail;
 
                 t = mfree(t);
         } else if (linkat(fd, "", dfd, fn, AT_EMPTY_PATH) < 0) {
                 r = -errno;
-                goto finish;
+                goto fail;
         }
 
         if (fsync(dfd) < 0) {
                 r = -errno;
-                goto finish;
+                goto fail;
         }
 
         if (ret_data) {
@@ -230,7 +281,7 @@ static int make_credential_host_secret(
                 copy = memdup(buf.data, sizeof(buf.data));
                 if (!copy) {
                         r = -ENOMEM;
-                        goto finish;
+                        goto fail;
                 }
 
                 *ret_data = copy;
@@ -239,13 +290,12 @@ static int make_credential_host_secret(
         if (ret_size)
                 *ret_size = sizeof(buf.data);
 
-        r = 0;
+        return 0;
 
-finish:
+fail:
         if (t && unlinkat(dfd, t, 0) < 0)
                 log_debug_errno(errno, "Failed to remove temporary credential key: %m");
 
-        explicit_bzero_safe(&buf, sizeof(buf));
         return r;
 }