#!/usr/bin/env ruby # frozen_string_literal: true # taken from https://gitlab.com/gitlab-org/gitaly/-/blob/master/scripts/security-harness require 'digest' require 'fileutils' if ENV['NO_COLOR'] SHELL_RED = '' SHELL_GREEN = '' SHELL_YELLOW = '' SHELL_CLEAR = '' else SHELL_RED = "\e[1;31m" SHELL_GREEN = "\e[1;32m" SHELL_YELLOW = "\e[1;33m" SHELL_CLEAR = "\e[0m" end HOOK_PATH = File.expand_path("../.git/hooks/pre-push", __dir__) HOOK_DATA = <<~HOOK #!/usr/bin/env bash set -e url="$2" harness=`dirname "$0"`/../security_harness if [ -e "$harness" ] then if [[ "$url" != *"gitlab-org/security/"* ]] then echo "Pushing to remotes other than gitlab.com/gitlab-org/security has been disabled!" echo "Run scripts/security-harness to disable this check." echo exit 1 fi fi HOOK def write_hook FileUtils.mkdir_p(File.dirname(HOOK_PATH)) File.open(HOOK_PATH, 'w') do |file| file.write(HOOK_DATA) end File.chmod(0755, HOOK_PATH) end # Toggle the harness on or off def toggle harness_path = File.expand_path('../.git/security_harness', __dir__) if File.exist?(harness_path) FileUtils.rm(harness_path) puts "#{SHELL_YELLOW}Security harness removed -- you can now push to all remotes.#{SHELL_CLEAR}" else FileUtils.touch(harness_path) puts "#{SHELL_GREEN}Security harness installed -- you will only be able to push to gitlab.com/gitlab-org/security!#{SHELL_CLEAR}" end end # If we were to change the script and then check for a pre-existing hook before # writing, the check would fail even if the user had an unmodified version of # the old hook. Checking previous version hashes allows us to safely overwrite a # script that differs from the current version, as long as it's an old one and # not custom. def previous_version?(dest_sum) # SHA256 hashes of previous iterations of the script contained in `DATA` %w[ 010bf0363a911ebab2bd5728d80795ed02388da51815f0b2530d08ae8ac574f0 ].include?(dest_sum) end if !File.exist?(HOOK_PATH) write_hook toggle else # Deal with a pre-existing hook source_sum = Digest::SHA256.hexdigest(HOOK_DATA) dest_sum = Digest::SHA256.file(HOOK_PATH).hexdigest if previous_version?(dest_sum) # Upgrading from a previous version, update in-place write_hook toggle elsif source_sum != dest_sum # Pre-existing hook we didn't create; do nothing puts "#{SHELL_RED}#{HOOK_PATH} exists and is different from our hook!" puts "Remove it and re-run this script to continue.#{SHELL_CLEAR}" exit 1 else # No hook update needed, just toggle toggle end end