diff --git a/lib/vagrant/util/downloader.rb b/lib/vagrant/util/downloader.rb index dee2cbaca..4793da194 100644 --- a/lib/vagrant/util/downloader.rb +++ b/lib/vagrant/util/downloader.rb @@ -1,6 +1,7 @@ require "uri" require "log4r" +require "digest" require "digest/md5" require "digest/sha1" require "vagrant/util/busy" @@ -23,7 +24,10 @@ module Vagrant # Supported file checksum CHECKSUM_MAP = { :md5 => Digest::MD5, - :sha1 => Digest::SHA1 + :sha1 => Digest::SHA1, + :sha256 => Digest::SHA256, + :sha384 => Digest::SHA384, + :sha512 => Digest::SHA512 }.freeze # Hosts that do not require notification on redirect @@ -68,7 +72,10 @@ module Vagrant @location_trusted = options[:location_trusted] @checksums = { :md5 => options[:md5], - :sha1 => options[:sha1] + :sha1 => options[:sha1], + :sha256 => options[:sha256], + :sha384 => options[:sha384], + :sha512 => options[:sha512] } end diff --git a/plugins/provisioners/shell/config.rb b/plugins/provisioners/shell/config.rb index 18a9f1ebd..74a74cf13 100644 --- a/plugins/provisioners/shell/config.rb +++ b/plugins/provisioners/shell/config.rb @@ -7,6 +7,9 @@ module VagrantPlugins attr_accessor :path attr_accessor :md5 attr_accessor :sha1 + attr_accessor :sha256 + attr_accessor :sha384 + attr_accessor :sha512 attr_accessor :env attr_accessor :upload_path attr_accessor :args @@ -26,6 +29,9 @@ module VagrantPlugins @path = UNSET_VALUE @md5 = UNSET_VALUE @sha1 = UNSET_VALUE + @sha256 = UNSET_VALUE + @sha384 = UNSET_VALUE + @sha512 = UNSET_VALUE @env = UNSET_VALUE @upload_path = UNSET_VALUE @privileged = UNSET_VALUE @@ -45,6 +51,9 @@ module VagrantPlugins @path = nil if @path == UNSET_VALUE @md5 = nil if @md5 == UNSET_VALUE @sha1 = nil if @sha1 == UNSET_VALUE + @sha256 = nil if @sha256 == UNSET_VALUE + @sha384 = nil if @sha384 == UNSET_VALUE + @sha512 = nil if @sha512 == UNSET_VALUE @env = {} if @env == UNSET_VALUE @upload_path = "/tmp/vagrant-shell" if @upload_path == UNSET_VALUE @privileged = true if @privileged == UNSET_VALUE diff --git a/plugins/provisioners/shell/provisioner.rb b/plugins/provisioners/shell/provisioner.rb index 4b7cd0507..8175d82b7 100644 --- a/plugins/provisioners/shell/provisioner.rb +++ b/plugins/provisioners/shell/provisioner.rb @@ -253,7 +253,10 @@ module VagrantPlugins config.path, download_path, md5: config.md5, - sha1: config.sha1 + sha1: config.sha1, + sha256: config.sha256, + sha384: config.sha384, + sha512: config.sha512 ).download! ext = File.extname(config.path) script = download_path.read diff --git a/test/unit/plugins/provisioners/shell/provisioner_test.rb b/test/unit/plugins/provisioners/shell/provisioner_test.rb index 0ae5e8a68..a31e02b51 100644 --- a/test/unit/plugins/provisioners/shell/provisioner_test.rb +++ b/test/unit/plugins/provisioners/shell/provisioner_test.rb @@ -188,6 +188,9 @@ describe "Vagrant::Shell::Provisioner" do :binary => false, :md5 => nil, :sha1 => 'EXPECTED_VALUE', + :sha256 => nil, + :sha384 => nil, + :sha512 => nil, :reset => false, :reboot => false ) @@ -208,6 +211,111 @@ describe "Vagrant::Shell::Provisioner" do end end + context "that does not have matching sha256 checksum" do + let(:config) { + double( + :config, + :args => "doesn't matter", + :env => {}, + :upload_path => "arbitrary", + :remote? => true, + :path => "http://example.com/script.sh", + :binary => false, + :md5 => nil, + :sha1 => nil, + :sha256 => 'EXPECTED_VALUE', + :sha384 => nil, + :sha512 => nil, + :reset => false, + :reboot => false + ) + } + + let(:digest){ double("digest") } + before do + allow_any_instance_of(Vagrant::Util::Downloader).to receive(:execute_curl).and_return(true) + allow(digest).to receive(:file).and_return(digest) + expect(Digest::SHA256).to receive(:new).and_return(digest) + expect(digest).to receive(:hexdigest).and_return('INVALID_VALUE') + end + + it "should raise an exception" do + vsp = VagrantPlugins::Shell::Provisioner.new(machine, config) + + expect{ vsp.provision }.to raise_error(Vagrant::Errors::DownloaderChecksumError) + end + end + + context "that does not have matching sha384 checksum" do + let(:config) { + double( + :config, + :args => "doesn't matter", + :env => {}, + :upload_path => "arbitrary", + :remote? => true, + :path => "http://example.com/script.sh", + :binary => false, + :md5 => nil, + :sha1 => nil, + :sha256 => nil, + :sha384 => 'EXPECTED_VALUE', + :sha512 => nil, + :reset => false, + :reboot => false + ) + } + + let(:digest){ double("digest") } + before do + allow_any_instance_of(Vagrant::Util::Downloader).to receive(:execute_curl).and_return(true) + allow(digest).to receive(:file).and_return(digest) + expect(Digest::SHA384).to receive(:new).and_return(digest) + expect(digest).to receive(:hexdigest).and_return('INVALID_VALUE') + end + + it "should raise an exception" do + vsp = VagrantPlugins::Shell::Provisioner.new(machine, config) + + expect{ vsp.provision }.to raise_error(Vagrant::Errors::DownloaderChecksumError) + end + end + + context "that does not have matching sha512 checksum" do + let(:config) { + double( + :config, + :args => "doesn't matter", + :env => {}, + :upload_path => "arbitrary", + :remote? => true, + :path => "http://example.com/script.sh", + :binary => false, + :md5 => nil, + :sha1 => nil, + :sha256 => nil, + :sha384 => nil, + :sha512 => 'EXPECTED_VALUE', + :reset => false, + :reboot => false + ) + } + + let(:digest){ double("digest") } + before do + allow_any_instance_of(Vagrant::Util::Downloader).to receive(:execute_curl).and_return(true) + allow(digest).to receive(:file).and_return(digest) + expect(Digest::SHA512).to receive(:new).and_return(digest) + expect(digest).to receive(:hexdigest).and_return('INVALID_VALUE') + end + + it "should raise an exception" do + vsp = VagrantPlugins::Shell::Provisioner.new(machine, config) + + expect{ vsp.provision }.to raise_error(Vagrant::Errors::DownloaderChecksumError) + end + end + context "that does not have matching md5 checksum" do let(:config) { double( @@ -220,6 +328,9 @@ describe "Vagrant::Shell::Provisioner" do :binary => false, :md5 => 'EXPECTED_VALUE', :sha1 => nil, + :sha256 => nil, + :sha384 => nil, + :sha512 => nil, :reset => false, :reboot => false ) diff --git a/test/unit/vagrant/util/downloader_test.rb b/test/unit/vagrant/util/downloader_test.rb index 67a065cf9..a59318571 100644 --- a/test/unit/vagrant/util/downloader_test.rb +++ b/test/unit/vagrant/util/downloader_test.rb @@ -181,7 +181,7 @@ describe Vagrant::Util::Downloader do allow(digest).to receive(:file).and_return(digest) end - [Digest::MD5, Digest::SHA1].each do |klass| + [Digest::MD5, Digest::SHA1, Digest::SHA256, Digest::SHA384, Digest::SHA512].each do |klass| short_name = klass.to_s.split("::").last.downcase context "using #{short_name} digest" do diff --git a/website/source/docs/cli/box.html.md b/website/source/docs/cli/box.html.md index aa8e74110..cfc95725b 100644 --- a/website/source/docs/cli/box.html.md +++ b/website/source/docs/cli/box.html.md @@ -91,7 +91,8 @@ you are not using a catalog). included within the catalog entry. * `--checksum-type TYPE` - The type of checksum that `--checksum` is if it - is specified. Supported values are currently "md5", "sha1", and "sha256". + is specified. Supported values are currently "md5", "sha1", "sha256", + "sha384", and "sha512". * `--name VALUE` - Logical name for the box. This is the value that you would put into `config.vm.box` in your Vagrantfile. When adding a box from diff --git a/website/source/docs/provisioning/shell.html.md b/website/source/docs/provisioning/shell.html.md index 1d955ad6f..218cbc3b1 100644 --- a/website/source/docs/provisioning/shell.html.md +++ b/website/source/docs/provisioning/shell.html.md @@ -83,6 +83,12 @@ The remainder of the available options are optional: * `sha1` (string) - SHA1 checksum used to validate remotely downloaded shell files. +* `sha256` (string) - SHA256 checksum used to validate remotely downloaded shell files. + +* `sha384` (string) - SHA384 checksum used to validate remotely downloaded shell files. + +* `sha512` (string) - SHA512 checksum used to validate remotely downloaded shell files. + * `sensitive` (boolean) - Marks the Hash values used in the `env` option as sensitive and hides them from output. By default this is "false". diff --git a/website/source/docs/vagrantfile/machine_settings.html.md b/website/source/docs/vagrantfile/machine_settings.html.md index 44402dc65..f41e93a0b 100644 --- a/website/source/docs/vagrantfile/machine_settings.html.md +++ b/website/source/docs/vagrantfile/machine_settings.html.md @@ -46,7 +46,7 @@ when Vagrant must download the box. If this is specified, then * `config.vm.box_download_checksum_type` (string) - The type of checksum specified by `config.vm.box_download_checksum` (if any). Supported values are -currently "md5", "sha1", and "sha256". +currently "md5", "sha1", "sha256", "sha384", and "sha512". * `config.vm.box_download_client_cert` (string) - Path to a client certificate to use when downloading the box, if it is necessary. By default, no client