Vagrant: Powershell exit code 4294770688 (‭FFFD0000‬) during vagrant up

Created on 22 Nov 2018  ·  6Comments  ·  Source: hashicorp/vagrant

Vagrant version

Vagrant 2.2.1, (actually noticed the issue on 2.2.0 and upgraded in hope for a quick fix)

Host operating system

Windows 10.

Expected behavior

vagrant up should have started successfully, as it has for a long time before today.

Actual behavior

Error message is displayed (excerpts from debug output):

Vagrant requires administrator access to create SMB shares and
may request access to complete setup of configured shares.
 INFO subprocess: Starting process: ["C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\/powershell.EXE", "-NoLogo", "-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-Command", "$p = Start-Process -FilePath powershell -ArgumentList @('-NoLogo', '-NoProfile', '-NonInteractive', '-ExecutionPolicy', 'Bypass', '-EncodedCommand', 'JABwACAAPQAgAFMAdABhAHIAdAAtAFAAcgBvAGMAZQBzAHMAIAAtAEYAaQBsAGUAUABhAHQAaAAgAHAAbwB3AGUAcgBzAGgAZQBsAGwAIAAtAEEAcgBnAHUAbQBlAG4AdABMAGkAcwB0ACAAQAAoACcALQBOAG8ATABvAGcAbwAnACwAIAAnAC0ATgBvAFAAcgBvAGYAaQBsAGUAJwAsACAAJwAtAE4AbwBuAEkAbgB0AGUAcgBhAGMAdABpAHYAZQAnACwAIAAnAC0ARQB4AGUAYwB1AHQAaQBvAG4AUABvAGwAaQBjAHkAJwAsACAAJwBCAHkAcABhAHMAcwAnACwAIAAnAC0ARQBuAGMAbwBkAGUAZABDAG8AbQBtAGEAbgBkACcALAAgACcASgBnAEEAZwBBAEMASQBBAFEAdwBBADYAQQBDADgAQQBVAEEAQgB5AEEARwA4AEEAWgB3AEIAeQBBAEcARQBBAGIAUQBCAHoAQQBDADgAQQBWAGcAQgBoAEEARwBjAEEAYwBnAEIAaABBAEcANABBAGQAQQBBAHYAQQBHAFUAQQBiAFEAQgBpAEEARwBVAEEAWgBBAEIAawBBAEcAVQBBAFoAQQBBAHYAQQBHAGMAQQBaAFEAQgB0AEEASABNAEEATAB3AEEAeQBBAEMANABBAE0AZwBBAHUAQQBEAEUAQQBMAHcAQgBuAEEARwBVAEEAYgBRAEIAegBBAEMAOABBAGQAZwBCAGgAQQBHAGMAQQBjAGcAQgBoAEEARwA0AEEAZABBAEEAdABBAEQASQBBAEwAZwBBAHkAQQBDADQAQQBNAFEAQQB2AEEASABBAEEAYgBBAEIAMQBBAEcAYwBBAGEAUQBCAHUAQQBIAE0AQQBMAHcAQgBvAEEARwA4AEEAYwB3AEIAMABBAEgATQBBAEwAdwBCADMAQQBHAGsAQQBiAGcAQgBrAEEARwA4AEEAZAB3AEIAegBBAEMAOABBAGMAdwBCAGoAQQBIAEkAQQBhAFEAQgB3AEEASABRAEEAYwB3AEEAdgBBAEgATQBBAFoAUQBCADAAQQBGADgAQQBjAHcAQgBvAEEARwBFAEEAYwBnAEIAbABBAEMANABBAGMAQQBCAHoAQQBEAEUAQQBJAGcAQQBnAEEAQwBJAEEAUQB3AEEANgBBAEYAdwBBAFYAdwBCAHYAQQBIAEkAQQBhAHcAQgB6AEEASABBAEEAWQBRAEIAagBBAEcAVQBBAFgAQQBCAFMAQQBHAFUAQQBZAGcAQgBsAEEARwB3AEEAUQBRAEIAdQBBAEcAUQBBAFIAdwBCAHMAQQBHADgAQQBjAGcAQgA1AEEARgB3AEEAZABnAEIAdgBBAEcAdwBBAFkAZwBCADUAQQBGAHcAQQBkAHcAQgBsAEEARwBJAEEASQBnAEEAZwBBAEMASQBBAGQAZwBCAG4AQQBIAFEAQQBMAFEAQgBtAEEARABrAEEAWQBRAEIAaQBBAEQARQBBAFkAdwBBADAAQQBEAFUAQQBaAFEAQQAyAEEARABJAEEAWgBRAEIAbABBAEcAUQBBAFkAUQBCAGgAQQBHAFkAQQBaAEEAQQAwAEEARABrAEEAWQBnAEEANQBBAEcAWQBBAFoAQQBBAHgAQQBHAEkAQQBNAGcAQgBtAEEARABRAEEATgBBAEEAdwBBAEcATQBBAEwAUQBBADIAQQBEAEEAQQBZAHcAQgBoAEEARABrAEEATQB3AEEAdwBBAEQAWQBBAE8AUQBBADQAQQBEAGcAQQBZAGcAQQAwAEEARwBRAEEAWgBRAEEAMQBBAEcARQBBAFoAUQBBADAAQQBHAEkAQQBZAGcAQQB5AEEARABZAEEATQB3AEIAagBBAEQAWQBBAE0AQQBCAGgAQQBEAEEAQQBOAFEAQQB4AEEARwBVAEEASQBnAEEAZwBBAEMASQBBAGQAZwBCAG4AQQBIAFEAQQBMAFEAQgBtAEEARABrAEEAWQBRAEIAaQBBAEQARQBBAFkAdwBBADAAQQBEAFUAQQBaAFEAQQAyAEEARABJAEEAWgBRAEIAbABBAEcAUQBBAFkAUQBCAGgAQQBHAFkAQQBaAEEAQQAwAEEARABrAEEAWQBnAEEANQBBAEcAWQBBAFoAQQBBAHgAQQBHAEkAQQBNAGcAQgBtAEEARABRAEEATgBBAEEAdwBBAEcATQBBAEwAUQBBADIAQQBEAEEAQQBZAHcAQgBoAEEARABrAEEATQB3AEEAdwBBAEQAWQBBAE8AUQBBADQAQQBEAGcAQQBZAGcAQQAwAEEARwBRAEEAWgBRAEEAMQBBAEcARQBBAFoAUQBBADAAQQBHAEkAQQBZAGcAQQB5AEEARABZAEEATQB3AEIAagBBAEQAWQBBAE0AQQBCAGgAQQBEAEEAQQBOAFEAQQB4AEEARwBVAEEASQBnAEEAZwBBAEMASQBBAFEAdwBBADYAQQBGAHcAQQBWAHcAQgB2AEEASABJAEEAYQB3AEIAegBBAEgAQQBBAFkAUQBCAGoAQQBHAFUAQQBYAEEAQgBTAEEARwBVAEEAWQBnAEIAbABBAEcAdwBBAFEAUQBCAHUAQQBHAFEAQQBSAHcAQgBzAEEARwA4AEEAYwBnAEIANQBBAEYAdwBBAGQAZwBCAHYAQQBHAHcAQQBZAGcAQgA1AEEARgB3AEEAWgBBAEIAaABBAEgAUQBBAFkAUQBBAGkAQQBDAEEAQQBJAGcAQgAyAEEARwBjAEEAZABBAEEAdABBAEcAWQBBAE8AUQBCAGgAQQBHAEkAQQBNAFEAQgBqAEEARABRAEEATgBRAEIAbABBAEQAWQBBAE0AZwBCAGwAQQBHAFUAQQBaAEEAQgBoAEEARwBFAEEAWgBnAEIAawBBAEQAUQBBAE8AUQBCAGkAQQBEAGsAQQBaAGcAQgBrAEEARABFAEEAWQBnAEEAeQBBAEcAWQBBAE4AQQBBADAAQQBEAEEAQQBZAHcAQQB0AEEARABVAEEATgBBAEEAegBBAEQAQQBBAE0AQQBBADAAQQBHAEUAQQBNAGcAQQA1AEEARwBVAEEATwBRAEIAaQBBAEQAQQBBAFkAdwBBAHcAQQBEAGMAQQBaAEEAQQA0AEEARwBRAEEATgBBAEEAMgBBAEQAWQBBAE4AZwBCAG0AQQBEAEEAQQBOAGcAQQAxAEEARABRAEEAWgBnAEIAaABBAEcARQBBAE0AQQBBAGkAQQBDAEEAQQBJAGcAQgAyAEEARwBjAEEAZABBAEEAdABBAEcAWQBBAE8AUQBCAGgAQQBHAEkAQQBNAFEAQgBqAEEARABRAEEATgBRAEIAbABBAEQAWQBBAE0AZwBCAGwAQQBHAFUAQQBaAEEAQgBoAEEARwBFAEEAWgBnAEIAawBBAEQAUQBBAE8AUQBCAGkAQQBEAGsAQQBaAGcAQgBrAEEARABFAEEAWQBnAEEAeQBBAEcAWQBBAE4AQQBBADAAQQBEAEEAQQBZAHcAQQB0AEEARABVAEEATgBBAEEAegBBAEQAQQBBAE0AQQBBADAAQQBHAEUAQQBNAGcAQQA1AEEARwBVAEEATwBRAEIAaQBBAEQAQQBBAFkAdwBBAHcAQQBEAGMAQQBaAEEAQQA0AEEARwBRAEEATgBBAEEAMgBBAEQAWQBBAE4AZwBCAG0AQQBEAEEAQQBOAGcAQQAxAEEARABRAEEAWgBnAEIAaABBAEcARQBBAE0AQQBBAGkAQQBDAEEAQQBPAHcAQQBnAEEARwBVAEEAZQBBAEIAcABBAEgAUQBBAEkAQQBBAGsAQQBFAHcAQQBRAFEAQgBUAEEARgBRAEEAUgBRAEIAWQBBAEUAawBBAFYAQQBCAEQAQQBFADgAQQBSAEEAQgBGAEEARABzAEEAJwApACAALQBQAGEAcwBzAFQAaAByAHUAIAAtAFcAaQBuAGQAbwB3AFMAdAB5AGwAZQAgAEgAaQBkAGQAZQBuACAALQBXAGEAaQB0ACAALQBSAGUAZABpAHIAZQBjAHQAUwB0AGEAbgBkAGEAcgBkAE8AdQB0AHAAdQB0ACAAJwBDADoALwBVAHMAZQByAHMALwBDAFoAVQBLAE8AVwB-ADEALwBBAHAAcABEAGEAdABhAC8ATABvAGMAYQBsAC8AVABlAG0AcAAvAHYAYQBnAHIAYQBuAHQAMgAwADEAOAAxADEAMgAyAC0AMQA1ADcAMgAtADEAaQBiAHgAdABqAG8ALwBzAHQAZABvAHUAdAAuAHQAeAB0ACcAIAAtAFIAZQBkAGkAcgBlAGMAdABTAHQAYQBuAGQAYQByAGQARQByAHIAbwByACAAJwBDADoALwBVAHMAZQByAHMALwBDAFoAVQBLAE8AVwB-ADEALwBBAHAAcABEAGEAdABhAC8ATABvAGMAYQBsAC8AVABlAG0AcAAvAHYAYQBnAHIAYQBuAHQAMgAwADEAOAAxADEAMgAyAC0AMQA1ADcAMgAtADEAaQBiAHgAdABqAG8ALwBzAHQAZABlAHIAcgAuAHQAeAB0ACcAOwAgAGkAZgAoACQAcAApAHsAIABlAHgAaQB0ACAAJABwAC4ARQB4AGkAdABDAG8AZABlADsAIAB9AGUAbABzAGUAewAgAGUAeABpAHQAIAAxACAAfQA=') -PassThru -WindowStyle Hidden -Wait -Verb RunAs; if($p){ exit $p.ExitCode; }else{ exit 1 }"]
 INFO subprocess: Command not in installer, restoring original environment...DEBUG subprocess: Selecting on IO
DEBUG subprocess: Waiting for process to exit. Remaining to timeout: 31999
DEBUG subprocess: Exit status: 4294770688

and later:

 INFO interface: error: Exporting an SMB share failed! Details about the failure are shown
below. Please inspect the error message and correct any problems.

Host path:

Stderr:

Stdout:
Exporting an SMB share failed! Details about the failure are shown
below. Please inspect the error message and correct any problems.

My research

I think the error code indicates the command has not been executed because it was malformed. I tried to debug Vagrant::Util::PowerShell around here:

https://github.com/hashicorp/vagrant/blob/45766ad00e5567fe6706a84fe07ba922b442dc34/lib/vagrant/util/powershell.rb#L216-L227

I found that the EncodedCommand it has produced what appears to be a broken base64 string, see gist: https://gist.github.com/czukowski/9dba0e991ae3515a730ad13ef58f9411

Note how the decoded version breaks near -RedirectStandardOutput 'C:/Users/CZUKOWీୀჀ᱀ᰀᄀ᠀ᵀ᠀ୀᏀᬀᣀ

The content of dpath variable was: C:/Users/CZUKOW~1/AppData/Local/Temp/vagrant20181122-10048-pj7qli

It breaks exactly at the tilde char in short path. The user directory name (czukowski) does not have any weird characters in it. Everything was working perfectly just yesterday.

I'm not very familiar with Ruby, but I suppose Dir.mktmpdir("vagrant") is a built-in method?

Steps to reproduce

This must be something in my system. I am a long time Vagrant user, but today was the 1st time I encountered the issue, now it happens consistently on SMB share creation or pruning :(

encoding hoswindows

Most helpful comment

So I thought I'd give it a shot and try to debug it some more. I added a spec to powershell_test.rb to cover powerup_command method and try to figure out what values cause decoding issue. I've found that both path and args can affect it.

There are four test cases here:

  • for the temp dir, I used the same value: C:/Users/ADMINI~1/AppData/Local/Temp/vagrant20181122-10048-pj7qli
  • for path argument (to a Powershell script), I tried a really short path, C:/Vagrant/unset_share.ps1 and one that might resemble a real installation: C:/Vagrant/embedded/gems/2.2.1/gems/vagrant-2.2.1/plugins/hosts/windows/scripts/unset_share.ps1
  • for opts argument (representing SMB share names), I also used two values, one array of two short elements, ["vgt-folder-1", "vgt-folder-2"] and one array of a single long string that I've actually copied from above, ["vgt-f9ab1c45e62eedaafd49b9fd1b2f440c-543004a29e9b0c07d8d4666f0654faa0"]

From that I've produced four combinations which the test runs on:

  describe ".powerup_command" do
    let(:result) do
      Vagrant::Util::Subprocess::Result.new(exit_code, stdout, stderr)
    end
    let(:exit_code){ 0 }
    let(:stdout){ "" }
    let(:stderr){ "" }

    test_cases = [
      [
        "short path and arguments",
        "C:/Users/ADMINI~1/AppData/Local/Temp/vagrant20181122-10048-pj7qli",
        "C:/Vagrant/unset_share.ps1",
        [
          "vgt-folder-1",
          "vgt-folder-2",
        ],
      ],
      [
        "short path and long arguments",
        "C:/Users/ADMINI~1/AppData/Local/Temp/vagrant20181122-10048-pj7qli",
        "C:/Vagrant/unset_share.ps1",
        [
          "vgt-f9ab1c45e62eedaafd49b9fd1b2f440c-543004a29e9b0c07d8d4666f0654faa0",
        ],
      ],
      [
        "long path and short arguments",
        "C:/Users/ADMINI~1/AppData/Local/Temp/vagrant20181122-10048-pj7qli",
        "C:/Vagrant/embedded/gems/2.2.1/gems/vagrant-2.2.1/plugins/hosts/windows/scripts/unset_share.ps1",
        [
          "vgt-folder-1",
          "vgt-folder-2",
        ],
      ],
      [
        "long path and arguments",
        "C:/Users/ADMINI~1/AppData/Local/Temp/vagrant20181122-10048-pj7qli",
        "C:/Vagrant/embedded/gems/2.2.1/gems/vagrant-2.2.1/plugins/hosts/windows/scripts/unset_share.ps1",
        [
          "vgt-f9ab1c45e62eedaafd49b9fd1b2f440c-543004a29e9b0c07d8d4666f0654faa0",
        ],
      ],
    ]

    test_cases.each do |description, tmpdir, path, args|

      it "should work with " + description do
        # Mock Subprocess.execute call
        allow(Vagrant::Util::Subprocess).to receive(:execute).and_return(result)
        # Mock Dir.mktmpdir call
        allow(Dir).to receive(:mktmpdir).and_yield(tmpdir)
        # Capture Base64.urlsafe_encode64 calls and do experiments on its arguments and return values
        expect(Base64).to receive(:urlsafe_encode64).twice.and_wrap_original do |m, *args|
          # Call original method
          encoded = m.call(*args)
          # Try decoding it back and compare to input argument, it always passes
          expect(args[0].b).to eq(Base64.urlsafe_decode64(encoded).b)
          # Try decoding it using strict_decode64 method, the result varies
          expect(args[0].b).to eq(Base64.strict_decode64(encoded).b)
          encoded
        end

        described_class.powerup_command(path, args, {})
      end
    end
  end

The results are:

 .powerup_command
    should work with short path and arguments
    should work with short path and long arguments
    should work with long path and short arguments
    should work with long path and arguments (FAILED - 1)

Failures:

  1) Vagrant::Util::PowerShell.powerup_command should work with long path and arguments
     Failure/Error: expect(args[0].b).to eq(Base64.strict_decode64(encoded).b)

     ArgumentError:
       invalid base64
     # ./test/unit/vagrant/util/powershell_test.rb:377:in `block (5 levels) in <top (required)>'
     # ./lib/vagrant/util/powershell.rb:227:in `block in powerup_command'
     # ./lib/vagrant/util/powershell.rb:211:in `powerup_command'
     # ./test/unit/vagrant/util/powershell_test.rb:381:in `block (4 levels) in <top (required)>'

Yes, I discovered there is more than one method to encode with Base64 in Ruby :)

I'm not sure I'm trying to do a legal thing here, by attempting a different Base64 decode method, but it passes 3 out of 4 times. The only docs I've been able to find for Powershell command line (linked below) does not seem to distinguish any special way to encode the command. I guess the question is which of those methods is the correct one to use, urlsafe_encode64 over strict_encode64.

I tried to edit the file in my Vagrant installation and replace urlsafe_encode64 with strict_encode64, and it worked, then revert my changes and the issue came back again, so it might seem as a solution, but I wasn't able to tell what exactly is messing up the encoded string when using urlsafe_encode64.

References:

https://docs.microsoft.com/en-us/powershell/scripting/core-powershell/console/powershell.exe-command-line-help
https://apidock.com/ruby/Base64/strict_encode64
https://apidock.com/ruby/Base64/urlsafe_encode64

All 6 comments

I am able to reproduce this issue using 2.2.1 on windows 10.
running vagrant up --debug throws:

 INFO subprocess: Starting process: ["C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\/powershell.EXE", "-NoLogo", "-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-Command", "$p = Start-Process -FilePath powershell -ArgumentList @('-NoLogo', '-NoProfile', '-NonInteractive', '-ExecutionPolicy', 'Bypass', '-EncodedCommand', 'JABwACAAPQAgAFMAdABhAHIAdAAtAFAAcgBvAGMAZQBzAHMAIAAtAEYAaQBsAGUAUABhAHQAaAAgAHAAbwB3AGUAcgBzAGgAZQBsAGwAIAAtAEEAcgBnAHUAbQBlAG4AdABMAGkAcwB0ACAAQAAoACcALQBOAG8ATABvAGcAbwAnACwAIAAnAC0ATgBvAFAAcgBvAGYAaQBsAGUAJwAsACAAJwAtAE4AbwBuAEkAbgB0AGUAcgBhAGMAdABpAHYAZQAnACwAIAAnAC0ARQB4AGUAYwB1AHQAaQBvAG4AUABvAGwAaQBjAHkAJwAsACAAJwBCAHkAcABhAHMAcwAnACwAIAAnAC0ARQBuAGMAbwBkAGUAZABDAG8AbQBtAGEAbgBkACcALAAgACcASgBnAEEAZwBBAEMASQBBAFEAdwBBADYAQQBDADgAQQBTAEEAQgBoAEEASABNAEEAYQBBAEIAcABBAEUATQBBAGIAdwBCAHkAQQBIAEEAQQBMAHcAQgBXAEEARwBFAEEAWgB3AEIAeQBBAEcARQBBAGIAZwBCADAAQQBDADgAQQBaAFEAQgB0AEEARwBJAEEAWgBRAEIAawBBAEcAUQBBAFoAUQBCAGsAQQBDADgAQQBaAHcAQgBsAEEARwAwAEEAYwB3AEEAdgBBAEQASQBBAEwAZwBBAHkAQQBDADQAQQBNAFEAQQB2AEEARwBjAEEAWgBRAEIAdABBAEgATQBBAEwAdwBCADIAQQBHAEUAQQBaAHcAQgB5AEEARwBFAEEAYgBnAEIAMABBAEMAMABBAE0AZwBBAHUAQQBEAEkAQQBMAGcAQQB4AEEAQwA4AEEAYwBBAEIAcwBBAEgAVQBBAFoAdwBCAHAAQQBHADQAQQBjAHcAQQB2AEEARwBnAEEAYgB3AEIAegBBAEgAUQBBAGMAdwBBAHYAQQBIAGMAQQBhAFEAQgB1AEEARwBRAEEAYgB3AEIAMwBBAEgATQBBAEwAdwBCAHoAQQBHAE0AQQBjAGcAQgBwAEEASABBAEEAZABBAEIAegBBAEMAOABBAGMAdwBCAGwAQQBIAFEAQQBYAHcAQgB6AEEARwBnAEEAWQBRAEIAeQBBAEcAVQBBAEwAZwBCAHcAQQBIAE0AQQBNAFEAQQBpAEEAQwBBAEEASQBnAEIARABBAEQAbwBBAFgAQQBCAG4AQQBHAGsAQQBkAEEAQgBjAEEASABZAEEAWQBRAEIAbgBBAEgASQBBAFkAUQBCAHUAQQBIAFEAQQBYAEEAQgBqAEEARwBRAEEAWQBRAEIAbQBBAEMAMABBAFYAdwBCAHAAQQBHADQAQQBaAEEAQgB2AEEASABjAEEAYwB3AEIAVABBAEcAVQBBAGMAZwBCADIAQQBHAFUAQQBjAGcAQgBUAEEASABRAEEAWQBRAEIAdQBBAEcAUQBBAFkAUQBCAHkAQQBHAFEAQQBJAGcAQQBnAEEAQwBJAEEAZABnAEIAbgBBAEgAUQBBAEwAUQBBAHoAQQBEAGcAQQBOAGcAQQB5AEEARABNAEEATwBBAEIAbQBBAEcASQBBAE0AdwBBAHkAQQBHAFkAQQBNAFEAQQB4AEEARwBNAEEATgBRAEEAeABBAEcAVQBBAFoAZwBBADMAQQBEAFEAQQBPAFEAQQA1AEEARABJAEEATwBBAEEAdwBBAEQAZwBBAE4AdwBBADUAQQBHAEUAQQBOAFEAQQA1AEEARABZAEEATABRAEEAMgBBAEcARQBBAFoAQQBBADEAQQBHAFkAQQBaAEEAQgBpAEEARwBNAEEAWQBnAEIAbQBBAEQASQBBAFoAUQBCAGgAQQBHAEUAQQBPAFEAQQB6AEEARwBJAEEAWgBBAEEAMgBBAEQASQBBAFoAZwBBADUAQQBEAEkAQQBNAHcAQQB6AEEARABNAEEAWQBRAEEAeQBBAEcAVQBBAE4AZwBCAGwAQQBEAFUAQQBJAGcAQQBnAEEAQwBJAEEAZABnAEIAbgBBAEgAUQBBAEwAUQBBAHoAQQBEAGcAQQBOAGcAQQB5AEEARABNAEEATwBBAEIAbQBBAEcASQBBAE0AdwBBAHkAQQBHAFkAQQBNAFEAQQB4AEEARwBNAEEATgBRAEEAeABBAEcAVQBBAFoAZwBBADMAQQBEAFEAQQBPAFEAQQA1AEEARABJAEEATwBBAEEAdwBBAEQAZwBBAE4AdwBBADUAQQBHAEUAQQBOAFEAQQA1AEEARABZAEEATABRAEEAMgBBAEcARQBBAFoAQQBBADEAQQBHAFkAQQBaAEEAQgBpAEEARwBNAEEAWQBnAEIAbQBBAEQASQBBAFoAUQBCAGgAQQBHAEUAQQBPAFEAQQB6AEEARwBJAEEAWgBBAEEAMgBBAEQASQBBAFoAZwBBADUAQQBEAEkAQQBNAHcAQQB6AEEARABNAEEAWQBRAEEAeQBBAEcAVQBBAE4AZwBCAGwAQQBEAFUAQQBJAGcAQQBnAEEARABzAEEASQBBAEIAbABBAEgAZwBBAGEAUQBCADAAQQBDAEEAQQBKAEEAQgBNAEEARQBFAEEAVQB3AEIAVQBBAEUAVQBBAFcAQQBCAEoAQQBGAFEAQQBRAHcAQgBQAEEARQBRAEEAUgBRAEEANwBBAEEAPQA9ACcAKQAgAC0AUABhAHMAcwBUAGgAcgB1ACAALQBXAGkAbgBkAG8AdwBTAHQAeQBsAGUAIABIAGkAZABkAGUAbgAgAC0AVwBhAGkAdAAgAC0AUgBlAGQAaQByAGUAYwB0AFMAdABhAG4AZABhAHIAZABPAHUAdABwAHUAdAAgACcAQwA6AC8AVQBzAGUAcgBzAC8ARwBHAFIASQBHAE4AfgAxAC8AQQBwAHAARABhAHQAYQAvAEwAbwBjAGEAbAAvAFQAZQBtAHAALwB2AGEAZwByAGEAbgB0ADIAMAAxADgAMQAxADIANwAtADEAOQAzADUANgAtADEANQA3ADgAcwBjAG8ALwBzAHQAZABvAHUAdAAuAHQAeAB0ACcAIAAtAFIAZQBkAGkAcgBlAGMAdABTAHQAYQBuAGQAYQByAGQARQByAHIAbwByACAAJwBDADoALwBVAHMAZQByAHMALwBHAEcAUgBJAEcATgB-ADEALwBBAHAAcABEAGEAdABhAC8ATABvAGMAYQBsAC8AVABlAG0AcAAvAHYAYQBnAHIAYQBuAHQAMgAwADEAOAAxADEAMgA3AC0AMQA5ADMANQA2AC0AMQA1ADcAOABzAGMAbwAvAHMAdABkAGUAcgByAC4AdAB4AHQAJwA7ACAAaQBmACgAJABwACkAewAgAGUAeABpAHQAIAAkAHAALgBFAHgAaQB0AEMAbwBkAGUAOwAgAH0AZQBsAHMAZQB7ACAAZQB4AGkAdAAgADEAIAB9AA==') -PassThru -WindowStyle Hidden -Wait -Verb RunAs; if($p){ exit $p.ExitCode; }else{ exit 1 }"]
 INFO subprocess: Command not in installer, restoring original environment...
DEBUG subprocess: Selecting on IO
DEBUG subprocess: Waiting for process to exit. Remaining to timeout: 31999
DEBUG subprocess: Exit status: 4294770688
ERROR warden: Error occurred: Exporting an SMB share failed! Details about the failure are shown
below. Please inspect the error message and correct any problems.

Host path:

Stderr:

Stdout:

Decrypting the base64 confirms there is an issue there.

fwiw, my current workaround is to change TEMP and TMP environment variables to a full path name, then vagrant up works correctly.

I have to do it in a cmd window and keep it handy because each new program has these values reverted to original. In the registry they're both set to %USERPROFILE%\AppData\Local\Temp and USERPROFILE is a full path (not 8.3), but somehow they become this:

> set
TEMP=C:\Users\CZUKOW~1\AppData\Local\Temp
TMP=C:\Users\CZUKOW~1\AppData\Local\Temp
USERPROFILE=C:\Users\czukowski

I can confirm this issue does not occur on previous Vagrant version 2.1.5.

So I thought I'd give it a shot and try to debug it some more. I added a spec to powershell_test.rb to cover powerup_command method and try to figure out what values cause decoding issue. I've found that both path and args can affect it.

There are four test cases here:

  • for the temp dir, I used the same value: C:/Users/ADMINI~1/AppData/Local/Temp/vagrant20181122-10048-pj7qli
  • for path argument (to a Powershell script), I tried a really short path, C:/Vagrant/unset_share.ps1 and one that might resemble a real installation: C:/Vagrant/embedded/gems/2.2.1/gems/vagrant-2.2.1/plugins/hosts/windows/scripts/unset_share.ps1
  • for opts argument (representing SMB share names), I also used two values, one array of two short elements, ["vgt-folder-1", "vgt-folder-2"] and one array of a single long string that I've actually copied from above, ["vgt-f9ab1c45e62eedaafd49b9fd1b2f440c-543004a29e9b0c07d8d4666f0654faa0"]

From that I've produced four combinations which the test runs on:

  describe ".powerup_command" do
    let(:result) do
      Vagrant::Util::Subprocess::Result.new(exit_code, stdout, stderr)
    end
    let(:exit_code){ 0 }
    let(:stdout){ "" }
    let(:stderr){ "" }

    test_cases = [
      [
        "short path and arguments",
        "C:/Users/ADMINI~1/AppData/Local/Temp/vagrant20181122-10048-pj7qli",
        "C:/Vagrant/unset_share.ps1",
        [
          "vgt-folder-1",
          "vgt-folder-2",
        ],
      ],
      [
        "short path and long arguments",
        "C:/Users/ADMINI~1/AppData/Local/Temp/vagrant20181122-10048-pj7qli",
        "C:/Vagrant/unset_share.ps1",
        [
          "vgt-f9ab1c45e62eedaafd49b9fd1b2f440c-543004a29e9b0c07d8d4666f0654faa0",
        ],
      ],
      [
        "long path and short arguments",
        "C:/Users/ADMINI~1/AppData/Local/Temp/vagrant20181122-10048-pj7qli",
        "C:/Vagrant/embedded/gems/2.2.1/gems/vagrant-2.2.1/plugins/hosts/windows/scripts/unset_share.ps1",
        [
          "vgt-folder-1",
          "vgt-folder-2",
        ],
      ],
      [
        "long path and arguments",
        "C:/Users/ADMINI~1/AppData/Local/Temp/vagrant20181122-10048-pj7qli",
        "C:/Vagrant/embedded/gems/2.2.1/gems/vagrant-2.2.1/plugins/hosts/windows/scripts/unset_share.ps1",
        [
          "vgt-f9ab1c45e62eedaafd49b9fd1b2f440c-543004a29e9b0c07d8d4666f0654faa0",
        ],
      ],
    ]

    test_cases.each do |description, tmpdir, path, args|

      it "should work with " + description do
        # Mock Subprocess.execute call
        allow(Vagrant::Util::Subprocess).to receive(:execute).and_return(result)
        # Mock Dir.mktmpdir call
        allow(Dir).to receive(:mktmpdir).and_yield(tmpdir)
        # Capture Base64.urlsafe_encode64 calls and do experiments on its arguments and return values
        expect(Base64).to receive(:urlsafe_encode64).twice.and_wrap_original do |m, *args|
          # Call original method
          encoded = m.call(*args)
          # Try decoding it back and compare to input argument, it always passes
          expect(args[0].b).to eq(Base64.urlsafe_decode64(encoded).b)
          # Try decoding it using strict_decode64 method, the result varies
          expect(args[0].b).to eq(Base64.strict_decode64(encoded).b)
          encoded
        end

        described_class.powerup_command(path, args, {})
      end
    end
  end

The results are:

 .powerup_command
    should work with short path and arguments
    should work with short path and long arguments
    should work with long path and short arguments
    should work with long path and arguments (FAILED - 1)

Failures:

  1) Vagrant::Util::PowerShell.powerup_command should work with long path and arguments
     Failure/Error: expect(args[0].b).to eq(Base64.strict_decode64(encoded).b)

     ArgumentError:
       invalid base64
     # ./test/unit/vagrant/util/powershell_test.rb:377:in `block (5 levels) in <top (required)>'
     # ./lib/vagrant/util/powershell.rb:227:in `block in powerup_command'
     # ./lib/vagrant/util/powershell.rb:211:in `powerup_command'
     # ./test/unit/vagrant/util/powershell_test.rb:381:in `block (4 levels) in <top (required)>'

Yes, I discovered there is more than one method to encode with Base64 in Ruby :)

I'm not sure I'm trying to do a legal thing here, by attempting a different Base64 decode method, but it passes 3 out of 4 times. The only docs I've been able to find for Powershell command line (linked below) does not seem to distinguish any special way to encode the command. I guess the question is which of those methods is the correct one to use, urlsafe_encode64 over strict_encode64.

I tried to edit the file in my Vagrant installation and replace urlsafe_encode64 with strict_encode64, and it worked, then revert my changes and the issue came back again, so it might seem as a solution, but I wasn't able to tell what exactly is messing up the encoded string when using urlsafe_encode64.

References:

https://docs.microsoft.com/en-us/powershell/scripting/core-powershell/console/powershell.exe-command-line-help
https://apidock.com/ruby/Base64/strict_encode64
https://apidock.com/ruby/Base64/urlsafe_encode64

@czukowski Thank you very much for digging into this and locating the root cause!

I'm going to lock this issue because it has been closed for _30 days_ ⏳. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

Was this page helpful?
0 / 5 - 0 ratings