Explorar el Código

spry keys: spawn statum-genkeys --out via a 0600 temp file (SA-12 follow-up)

statum-genkeys no longer prints secret key halves to stdout, so the CLI
that consumed its stdout JSON now passes --out and reads the file instead.
The temp path is unlinked in a finally block; secrets never pass through a
pipe. (DirUtils.make_tmp was avoided deliberately: g_dir_make_tmp creates a
directory, which the tool cannot write as a file.)

Verified end to end: spry keys --tools-dir <dir> -o web-config.json writes
six keys at mode 0600, leaves no temp residue, and a second run reports
nothing to do.
Task Agent hace 4 semanas
padre
commit
35fb3b9cd9
Se han modificado 1 ficheros con 35 adiciones y 13 borrados
  1. 35 13
      tools/spry/Keys.vala

+ 35 - 13
tools/spry/Keys.vala

@@ -80,26 +80,48 @@ namespace Spry.Cli {
             }
         }
 
+        /**
+         * Spawns `statum-genkeys --out <tempfile>` and returns the generated
+         * "statum" object.
+         *
+         * Since Statum's SA-12 fix the tool never prints secret halves to
+         * stdout (shell history, CI logs and pipe captures would acquire
+         * them); the full material is written straight to a temporary file at
+         * mode 0600, read here, and unlinked immediately.
+         */
         private static Json.Object spawn_genkeys(string? tools_dir, string? libdir) throws Error {
             var tool = Tools.resolve("statum-genkeys", tools_dir);
             var launcher = new SubprocessLauncher(SubprocessFlags.STDOUT_PIPE | SubprocessFlags.STDERR_PIPE);
             Tools.apply_env(launcher, libdir);
-            var process = launcher.spawnv({ tool });
 
-            string stdout_buf;
-            string stderr_buf;
-            process.communicate_utf8(null, null, out stdout_buf, out stderr_buf);
-            if (!process.get_successful()) {
-                throw Generator.cli_error("statum-genkeys failed: %s", (stderr_buf ?? "").strip());
-            }
+            // A temporary FILE (g_dir_make_tmp would give a directory).
+            var keyfile = GLib.Path.build_filename(
+                Environment.get_tmp_dir(),
+                "statum-genkeys-%s.json".printf(((uint64) Random.int_range(0, 1 << 30)).to_string()));
+            try {
+                var process = launcher.spawnv({ tool, "--out", keyfile });
+                string stdout_buf;
+                string stderr_buf;
+                process.communicate_utf8(null, null, out stdout_buf, out stderr_buf);
+                if (!process.get_successful()) {
+                    throw Generator.cli_error("statum-genkeys failed: %s", (stderr_buf ?? "").strip());
+                }
 
-            var parser = new Parser();
-            parser.load_from_data(stdout_buf ?? "");
-            var root = parser.get_root();
-            if (root == null || root.get_object() == null || !((!)root).get_object().has_member("statum")) {
-                throw Generator.cli_error("unexpected statum-genkeys output");
+                string contents;
+                if (!FileUtils.get_contents(keyfile, out contents)) {
+                    throw Generator.cli_error("statum-genkeys did not produce %s", keyfile);
+                }
+
+                var parser = new Parser();
+                parser.load_from_data(contents);
+                var root = parser.get_root();
+                if (root == null || root.get_object() == null || !((!)root).get_object().has_member("statum")) {
+                    throw Generator.cli_error("unexpected statum-genkeys output");
+                }
+                return ((!)root).get_object().get_object_member("statum");
+            } finally {
+                FileUtils.unlink(keyfile);
             }
-            return ((!)root).get_object().get_object_member("statum");
         }
 
         /**