initial commit master v1
authorJann Horn <jann@thejh.net>
Fri, 1 May 2015 13:32:40 +0000 (15:32 +0200)
committerJann Horn <jann@thejh.net>
Fri, 1 May 2015 13:32:40 +0000 (15:32 +0200)
LICENSE [new file with mode: 0644]
README [new file with mode: 0644]
safeget [new file with mode: 0755]

diff --git a/LICENSE b/LICENSE
new file mode 100644 (file)
index 0000000..00d2e13
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,24 @@
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+
+In jurisdictions that recognize copyright laws, the author or authors
+of this software dedicate any and all copyright interest in the
+software to the public domain. We make this dedication for the benefit
+of the public at large and to the detriment of our heirs and
+successors. We intend this dedication to be an overt act of
+relinquishment in perpetuity of all present and future rights to this
+software under copyright law.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+For more information, please refer to <http://unlicense.org/>
\ No newline at end of file
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..7f8bfe1
--- /dev/null
+++ b/README
@@ -0,0 +1,5 @@
+This is a quick-and-dirty tool to give you some degree of assurance that downloads (especially software downloads) have not been
+tampered with in transit, even if the files are served over plain HTTP and no signatures are available.
+It first downloads the file locally, then connects to all hosts listed in ~/.multiget_machines via ssh, downloads the same file
+from there and calculates a SHA256 checksum, which is transmitted back to you. The checksums are then compared automatically, and
+the file will not be placed in the specified destination (and you'll see a warning) if not all of the checksums are equal.
diff --git a/safeget b/safeget
new file mode 100755 (executable)
index 0000000..c2bf61d
--- /dev/null
+++ b/safeget
@@ -0,0 +1,42 @@
+#!/bin/bash
+if [ ! -n "$2" ]; then
+  echo "invocation: safeget <URL> <targetfile>"
+  exit 2
+fi
+
+echo "downloading locally..."
+realdest="$(mktemp)"
+checksum="$(curl -- "$1" | tee -- "$realdest" | sha256sum - | cut -d' ' -f1 | tr -d '\n')"
+echo "got checksum:"
+echo "$checksum"
+echo ""
+
+mismatch_detected=0
+
+echo "downloading on remote machines..."
+for machine in $(cat ~/.multiget_machines); do
+  echo -ne "  downloading from $machine...                                                     \r"
+
+  # yuck! uhm... nothing to see here.
+  # things this tries to defend against:
+  #  - special chars in the URL that cause local and remote curl to see different URLs (but of course, defending
+  #    against that only makes limited sense)
+  #  - remote system sends us special chars and wipes previous warnings from the screen
+  remote_sha256_unsanitized="$(echo -n "$1" | base64 -w0 | ssh -- "$machine" curl -- '"$(base64 -d)"' '|' sha256sum - 2>/dev/null)"
+  remote_sha256="$(echo -n "$remote_sha256_unsanitized" | cut -d' ' -f1 | tr -cd '0123456789abcdef')"
+
+  if echo -n "$remote_sha256" | grep -vFq -- "$checksum"; then
+    echo -e '\E[1;33;44m'"DIFFERENT CHECKSUM FROM $machine:\n$remote_sha256"'\E[0m'
+    mismatch_detected=1
+  fi
+done
+echo -e "done                                                                          "
+
+if [ "$mismatch_detected" -eq 0 ]; then
+  echo "moving file to $2..."
+  mv -- "$realdest" "$2"
+  echo "done"
+else
+  echo "NOT moving temporary download from $realdest to $2 because verification failed"
+  exit 1
+fi