summary refs log tree commit diff
path: root/pkgs/build-support/replace-secret
diff options
context:
space:
mode:
authortalyz <kim.lindberger@gmail.com>2021-05-04 15:59:15 +0200
committertalyz <kim.lindberger@gmail.com>2021-05-19 09:32:00 +0200
commit27f8f6956a1f44884b1ff07a71174a308e818e99 (patch)
treecb6982ebf04d2ba08b56ead3b6302188c14417bc /pkgs/build-support/replace-secret
parent7cefeafb1141bae3aad85518079397499ede1866 (diff)
downloadnixpkgs-27f8f6956a1f44884b1ff07a71174a308e818e99.tar
nixpkgs-27f8f6956a1f44884b1ff07a71174a308e818e99.tar.gz
nixpkgs-27f8f6956a1f44884b1ff07a71174a308e818e99.tar.bz2
nixpkgs-27f8f6956a1f44884b1ff07a71174a308e818e99.tar.lz
nixpkgs-27f8f6956a1f44884b1ff07a71174a308e818e99.tar.xz
nixpkgs-27f8f6956a1f44884b1ff07a71174a308e818e99.tar.zst
nixpkgs-27f8f6956a1f44884b1ff07a71174a308e818e99.zip
replace-secret: Init
Add a small utility script which securely replaces secrets in
files. Doing this with `sed`, `replace-literal` or similar utilities
leaks the secrets through the spawned process' `/proc/<pid>/cmdline` file.
Diffstat (limited to 'pkgs/build-support/replace-secret')
-rw-r--r--pkgs/build-support/replace-secret/replace-secret.nix35
-rwxr-xr-xpkgs/build-support/replace-secret/replace-secret.py28
-rw-r--r--pkgs/build-support/replace-secret/test/expected_long_output30
-rw-r--r--pkgs/build-support/replace-secret/test/expected_short_output4
-rw-r--r--pkgs/build-support/replace-secret/test/input_file4
-rw-r--r--pkgs/build-support/replace-secret/test/passwd1
-rw-r--r--pkgs/build-support/replace-secret/test/rsa27
7 files changed, 129 insertions, 0 deletions
diff --git a/pkgs/build-support/replace-secret/replace-secret.nix b/pkgs/build-support/replace-secret/replace-secret.nix
new file mode 100644
index 00000000000..e04d1aed5f7
--- /dev/null
+++ b/pkgs/build-support/replace-secret/replace-secret.nix
@@ -0,0 +1,35 @@
+{ stdenv, lib, python3 }:
+
+stdenv.mkDerivation {
+  name = "replace-secret";
+  buildInputs = [ python3 ];
+  phases = [ "installPhase" "checkPhase" ];
+  installPhase = ''
+    install -D ${./replace-secret.py} $out/bin/replace-secret
+    patchShebangs $out
+  '';
+  doCheck = true;
+  checkPhase = ''
+    install -m 0600 ${./test/input_file} long_test
+    $out/bin/replace-secret "replace this" ${./test/passwd} long_test
+    $out/bin/replace-secret "and this" ${./test/rsa} long_test
+    diff ${./test/expected_long_output} long_test
+
+    install -m 0600 ${./test/input_file} short_test
+    $out/bin/replace-secret "replace this" <(echo "a") short_test
+    $out/bin/replace-secret "and this" <(echo "b") short_test
+    diff ${./test/expected_short_output} short_test
+  '';
+  meta = with lib; {
+    platforms = platforms.all;
+    maintainers = with maintainers; [ talyz ];
+    license = licenses.mit;
+    description = "Replace a string in one file with a secret from a second file";
+    longDescription = ''
+      Replace a string in one file with a secret from a second file.
+
+      Since the secret is read from a file, it won't be leaked through
+      '/proc/<pid>/cmdline', unlike when 'sed' or 'replace' is used.
+    '';
+  };
+}
diff --git a/pkgs/build-support/replace-secret/replace-secret.py b/pkgs/build-support/replace-secret/replace-secret.py
new file mode 100755
index 00000000000..30ff41d491b
--- /dev/null
+++ b/pkgs/build-support/replace-secret/replace-secret.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python
+
+import argparse
+from argparse import RawDescriptionHelpFormatter
+
+description = """
+Replace a string in one file with a secret from a second file.
+
+Since the secret is read from a file, it won't be leaked through
+'/proc/<pid>/cmdline', unlike when 'sed' or 'replace' is used.
+"""
+
+parser = argparse.ArgumentParser(
+    description=description,
+    formatter_class=RawDescriptionHelpFormatter
+)
+parser.add_argument("string_to_replace", help="the string to replace")
+parser.add_argument("secret_file", help="the file containing the secret")
+parser.add_argument("file", help="the file to perform the replacement on")
+args = parser.parse_args()
+
+with open(args.secret_file) as sf, open(args.file, 'r+') as f:
+    old = f.read()
+    secret = sf.read().strip("\n")
+    new_content = old.replace(args.string_to_replace, secret)
+    f.seek(0)
+    f.write(new_content)
+    f.truncate()
diff --git a/pkgs/build-support/replace-secret/test/expected_long_output b/pkgs/build-support/replace-secret/test/expected_long_output
new file mode 100644
index 00000000000..37bd66b905f
--- /dev/null
+++ b/pkgs/build-support/replace-secret/test/expected_long_output
@@ -0,0 +1,30 @@
+beginning
+middle $6$UcbJUl5g$HRMfKNKsLTfVbcQb.P5o0bmZUfHDYkWseMSuZ8F5jSIGZZcI3Jnit23f8ZeZOGi4KL86HVM9RYqrpYySOu/fl0 not this
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAzrru6v5tfwQl6L+rOUjtLo8kbhMUlCLXP7TYngSGrkzPMWe+
+0gB04UAmiPZXfBmvj5fPqYiFjIaEDHE/SD41vJB/RJKKtId2gCAIHhBLkbr+4+60
+yEbLkJci5i4kJC1dt8OKFEzXkaVnwOSgjH+0NwO3bstZ+E70zMXS9+NS71qGsIEb
+5J1TnacwW/u6CdFyakLljWOXOR14rLIpiPBBFLf+oZiepjIhlWXWHqsxZOb7zMI0
+T4W5WJ2dwGFsJ8rkYaGZ+A5qzYbi/KmHqaSPaNDsyoi7yJhAhKPByALJU916+8QO
+xOnqZxWGki3PDzCslRwW4i3mGbZlBQMnlfbN3QIDAQABAoIBAHDn1W7QkFrLmCy6
+6bf6pVdFZF8d2qJhOPAZRClhTXFKj+pqv+QPzcXr9F/fMr6bhK/G+Oqdnlq2aM4m
+16oMF+spe+impEyeo1CsreJFghBQcb9o8qFjUPBiKvROBP0hLcscZ4BYy29HSBgo
+harWYEWfqQJA251q+fYQoP0z0WrZKddOZbRRnJ0ICRxAE7IEtDT6EYt8R9oGi2j4
+/rpdW+rYGjW3TcmzdR7lpVMJRLlbMbSdR8n6cI6rnfySygcoE5tFX5t/YZSNbBPg
+GebKCbEHYNTTG8bC1qjUyzlbEQ6XYWvFO7HTKU7105XpjYTQFByeo0IVkin0o5KW
+t7eQWb0CgYEA6zZUWsYoQ13nXEU6Ky89Q9uhesMfaJ/F2X5ikQSRqRvrR3QR+ULe
+eNnCl10O9SiFpR4b5gSbLSHMffxGN60P1nEO4CiIKE+gOii8Kdk5htIJFy/dcZUc
+PuPM+zD9/6Is5sAWUZo45bnT6685h6EjM2+6zNZtx/XMjSfWbHaY+HMCgYEA4QAy
+6ZEgd6FHnNfM/q2o8XU3d6OCdhcu26u6ydnCalbSpPSKWOi6gnHK4ZnGdryXgIYw
+hRkvYINfiONkShYytotIh4YxUbgpwdvJRyKa2ZdWhcMmtFzZOcEVzQTKBasFT74C
+Wo0iybZ++XZh3M0+n7oyyx39aR7diZ+/zq6PnG8CgYB8B1QH4cHNdDDRqPd5WhmW
+NLQ7xbREOSvc+hYDnkMoxz4TmZL4u1gQpdNEeZ+visSeQvg3HGqvK8lnDaYBKdLW
+IxvS+8yAZSx6PoyqDI+XFh4RCf5dLGGOkBTAyB7Hs761lsiuEwK5sHmdJ/LQIBot
+v1bjOJb/AA/yxvT8kLUtHQKBgGIA9iwqXJv/EfRNQytDdS0HQ4vHGtJZMr3YRVoa
+kcZD3yieo4wqguLCsf4mPv4FE3CWAphW6f39+yTi9xIWLSy56nOtjdnsf7PDCh8E
+AbL5amSFJly1fKDda6OLjHt/jKa5Osk6ZIa8CP6cA/BrLfXg4rL6cyDQouqJPMDH
+5CHdAoGBAIChjbTyoYvANkoANCK4SuqLUYeiYREfiM3sqHe1xirK1PPHw03ZLITl
+ltjo9qE6kPXWcTBVckTKGFlntyCT283FC0/vMmHo8dTdtxF4/wSbkqs3ORuJ3p5J
+cNtLYGD3vgwLmg6tTur4U60XN+tYDzWGteez8J9GwTMfKJmuS9af
+-----END RSA PRIVATE KEY-----
+end
diff --git a/pkgs/build-support/replace-secret/test/expected_short_output b/pkgs/build-support/replace-secret/test/expected_short_output
new file mode 100644
index 00000000000..3c81b2e2f99
--- /dev/null
+++ b/pkgs/build-support/replace-secret/test/expected_short_output
@@ -0,0 +1,4 @@
+beginning
+middle a not this
+b
+end
diff --git a/pkgs/build-support/replace-secret/test/input_file b/pkgs/build-support/replace-secret/test/input_file
new file mode 100644
index 00000000000..1e7eadfaab2
--- /dev/null
+++ b/pkgs/build-support/replace-secret/test/input_file
@@ -0,0 +1,4 @@
+beginning
+middle replace this not this
+and this
+end
diff --git a/pkgs/build-support/replace-secret/test/passwd b/pkgs/build-support/replace-secret/test/passwd
new file mode 100644
index 00000000000..68f266226e4
--- /dev/null
+++ b/pkgs/build-support/replace-secret/test/passwd
@@ -0,0 +1 @@
+$6$UcbJUl5g$HRMfKNKsLTfVbcQb.P5o0bmZUfHDYkWseMSuZ8F5jSIGZZcI3Jnit23f8ZeZOGi4KL86HVM9RYqrpYySOu/fl0
diff --git a/pkgs/build-support/replace-secret/test/rsa b/pkgs/build-support/replace-secret/test/rsa
new file mode 100644
index 00000000000..138cc99ed22
--- /dev/null
+++ b/pkgs/build-support/replace-secret/test/rsa
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAzrru6v5tfwQl6L+rOUjtLo8kbhMUlCLXP7TYngSGrkzPMWe+
+0gB04UAmiPZXfBmvj5fPqYiFjIaEDHE/SD41vJB/RJKKtId2gCAIHhBLkbr+4+60
+yEbLkJci5i4kJC1dt8OKFEzXkaVnwOSgjH+0NwO3bstZ+E70zMXS9+NS71qGsIEb
+5J1TnacwW/u6CdFyakLljWOXOR14rLIpiPBBFLf+oZiepjIhlWXWHqsxZOb7zMI0
+T4W5WJ2dwGFsJ8rkYaGZ+A5qzYbi/KmHqaSPaNDsyoi7yJhAhKPByALJU916+8QO
+xOnqZxWGki3PDzCslRwW4i3mGbZlBQMnlfbN3QIDAQABAoIBAHDn1W7QkFrLmCy6
+6bf6pVdFZF8d2qJhOPAZRClhTXFKj+pqv+QPzcXr9F/fMr6bhK/G+Oqdnlq2aM4m
+16oMF+spe+impEyeo1CsreJFghBQcb9o8qFjUPBiKvROBP0hLcscZ4BYy29HSBgo
+harWYEWfqQJA251q+fYQoP0z0WrZKddOZbRRnJ0ICRxAE7IEtDT6EYt8R9oGi2j4
+/rpdW+rYGjW3TcmzdR7lpVMJRLlbMbSdR8n6cI6rnfySygcoE5tFX5t/YZSNbBPg
+GebKCbEHYNTTG8bC1qjUyzlbEQ6XYWvFO7HTKU7105XpjYTQFByeo0IVkin0o5KW
+t7eQWb0CgYEA6zZUWsYoQ13nXEU6Ky89Q9uhesMfaJ/F2X5ikQSRqRvrR3QR+ULe
+eNnCl10O9SiFpR4b5gSbLSHMffxGN60P1nEO4CiIKE+gOii8Kdk5htIJFy/dcZUc
+PuPM+zD9/6Is5sAWUZo45bnT6685h6EjM2+6zNZtx/XMjSfWbHaY+HMCgYEA4QAy
+6ZEgd6FHnNfM/q2o8XU3d6OCdhcu26u6ydnCalbSpPSKWOi6gnHK4ZnGdryXgIYw
+hRkvYINfiONkShYytotIh4YxUbgpwdvJRyKa2ZdWhcMmtFzZOcEVzQTKBasFT74C
+Wo0iybZ++XZh3M0+n7oyyx39aR7diZ+/zq6PnG8CgYB8B1QH4cHNdDDRqPd5WhmW
+NLQ7xbREOSvc+hYDnkMoxz4TmZL4u1gQpdNEeZ+visSeQvg3HGqvK8lnDaYBKdLW
+IxvS+8yAZSx6PoyqDI+XFh4RCf5dLGGOkBTAyB7Hs761lsiuEwK5sHmdJ/LQIBot
+v1bjOJb/AA/yxvT8kLUtHQKBgGIA9iwqXJv/EfRNQytDdS0HQ4vHGtJZMr3YRVoa
+kcZD3yieo4wqguLCsf4mPv4FE3CWAphW6f39+yTi9xIWLSy56nOtjdnsf7PDCh8E
+AbL5amSFJly1fKDda6OLjHt/jKa5Osk6ZIa8CP6cA/BrLfXg4rL6cyDQouqJPMDH
+5CHdAoGBAIChjbTyoYvANkoANCK4SuqLUYeiYREfiM3sqHe1xirK1PPHw03ZLITl
+ltjo9qE6kPXWcTBVckTKGFlntyCT283FC0/vMmHo8dTdtxF4/wSbkqs3ORuJ3p5J
+cNtLYGD3vgwLmg6tTur4U60XN+tYDzWGteez8J9GwTMfKJmuS9af
+-----END RSA PRIVATE KEY-----