Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PowerShell Core editions cannot properly run deploy_stack.ps1 #1475

Closed
3 tasks done
arnydo opened this issue Mar 11, 2020 · 9 comments
Closed
3 tasks done

PowerShell Core editions cannot properly run deploy_stack.ps1 #1475

arnydo opened this issue Mar 11, 2020 · 9 comments

Comments

@arnydo
Copy link

arnydo commented Mar 11, 2020

My actions before raising this issue

Currently, .NET Core does not support System.Web.dll which causes [System.Web.Security.Membership]::GeneratePassword(14, 5) to fail.

When running the script with a Core edition of PowerShell such as 6.0.0 or 7.0.0 the script runs but fails to generate a password. The script continues to completion with no way to access the UI or CLI since the password is unknown/no-set.

Expected Behaviour

It is expected that when running deploy_stack.ps1 in any version of PowerShell that the script will run successfully.

Current Behaviour

In this case, PowerShell Core cannot use the system.web.security assembly, therefore, cannot run $password = [System.Web.Security.Membership]::GeneratePassword(24,5).

The script runs through until completion but does not successfully set the password to be used.

Here is the output of the script running in 7.0.0.

PS>.\deploy_stack.ps1
InvalidOperation: C:\Working\faas\deploy_stack.ps1:30
Line |
  30 |      $password = [System.Web.Security.Membership]::GeneratePassword(24|                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | Unable to find type [System.Web.Security.Membership].

MethodInvocationException: C:\Working\faas\deploy_stack.ps1:36
Line |
  36 |          $hash = $sha256.ComputeHash([System.Text.Encoding]::UTF8.GetB …
     |          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | Exception calling "GetBytes" with "1" argument(s): "Array cannot be null. (Parameter 'chars')"

MethodInvocationException: C:\Working\faas\deploy_stack.ps1:38
Line |
  38 |          $secret = [System.BitConverter]::ToString($hash).Replace('-',|          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | Exception calling "ToString" with "1" argument(s): "Value cannot be null. (Parameter 'value')"

Attempting to create credentials for gateway..

Possible Solution

  • The best solution is to determine an alternate method to generate (securely) a random password without requiring system.web.dll do to lack of support for Core PowerShell editions.

  • A temporary solution would be to add #Requires -PSEdition Desktop to at least notify the end-user that using a Core version of PowerShell will not work. It currently appears to complete but there is no way to log in.

Steps to Reproduce (for bugs)

  1. Open PowerShell Core (6.0.0, 7.0.0, etc.)
  2. Run deploy_stack.ps1 (using default parameters)

Context

Simply trying to run default installation/deployment of OpenFaas via Docker Swarm.

Your Environment

  • FaaS-CLI version ( Full output from: faas-cli version ): 0.1.6
======================================
======= Sonra Intelligence Ltd =======
=======    FaaS Python SDK     =======
=======     version 0.1.6      =======
======================================
  • Docker version docker version (e.g. Docker 17.0.05 ): 19.03.5

  • Are you using Docker Swarm or Kubernetes (FaaS-netes)? Swarm

  • Operating System and version (e.g. Linux, Windows, MacOS): Windows

  • Code example or link to GitHub repo or gist to reproduce problem: ./deploy_stack.ps1

  • Other diagnostic information / logs from troubleshooting guide

PS>.\deploy_stack.ps1
InvalidOperation: C:\Working\faas\deploy_stack.ps1:30
Line |
  30 |      $password = [System.Web.Security.Membership]::GeneratePassword(24|                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | Unable to find type [System.Web.Security.Membership].

MethodInvocationException: C:\Working\faas\deploy_stack.ps1:36
Line |
  36 |          $hash = $sha256.ComputeHash([System.Text.Encoding]::UTF8.GetB …
     |          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | Exception calling "GetBytes" with "1" argument(s): "Array cannot be null. (Parameter 'chars')"

MethodInvocationException: C:\Working\faas\deploy_stack.ps1:38
Line |
  38 |          $secret = [System.BitConverter]::ToString($hash).Replace('-',|          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | Exception calling "ToString" with "1" argument(s): "Value cannot be null. (Parameter 'value')"

Attempting to create credentials for gateway..

Next steps

You may join Slack for community support.

@burtonr
Copy link
Contributor

burtonr commented Mar 11, 2020

Thanks for bringing this up!

There are no real password requirements as far as OpenFaaS is concerned. In the deploy_stack file, we are simply doing a service for the user in generating a random string to be used as a password that can not be easily guessed.

I'm fairly certain there is a function (or commandlet) in PowerShell that is similar to the one used in our bash scripts:

secret=$(head -c 16 /dev/urandom| $sha_cmd | cut -d " " -f 1)

@arnydo
Copy link
Author

arnydo commented Mar 12, 2020

In that case, I put together this function that should mimic what the snippet is doing in the bash script.

function generatePassword {
    $b = [byte[]](1..16)
    (new-object Security.Cryptography.RNGCryptoServiceProvider).GetBytes($b)
    $string = [Text.encoding]::UTF8.GetBytes( -join ($b | ForEach-Object { [char[]](65..90 + 57..33)[$_%51] }))
    $hmacsha = New-Object System.Security.Cryptography.HMACSHA256
    $hash = $hmacsha.ComputeHash([Text.Encoding]::ASCII.GetBytes($string))
    $password = ([System.BitConverter]::ToString($hash) -replace '-', '').ToLower()
    return $password
}

A sample output would be: b9963b19b42e15b9b95e9ee1124aff4520974886f12f3f944629cca43737cffd

I have tested the function on these PowerShell versions:

  • 7.0.0
  • 5.1
  • 2.0

What are your thoughts?

@burtonr
Copy link
Contributor

burtonr commented Mar 12, 2020

I like it! It's great that it works across the versions and is self-contained within the script.

I'm surprised it's as complex as it is, but it does work (just tested on my Windows 5.1). I'd be happy with this in a PR. Thanks! 💯

@arnydo
Copy link
Author

arnydo commented Mar 12, 2020

Yes, it is a little longer than the bash version but I can't seem to find a way around it. in 5.1 there is a cmdlet Get-Hash -Algorithm SHA256 that would work perfect but doesn't seem to be available in Core/7.0.0.

Thank you for the feedback. I will submit a PR.

@arnydo
Copy link
Author

arnydo commented Mar 12, 2020

Okay, now that I am putting the new code into the actual depoy_stack.ps1 file I was able to shorten the code to this:

    $password = -join ((33..126) * 120 | Get-Random -Count 24 | ForEach-Object { [char]$_ })
    $secret = ""

@alexellis
Copy link
Member

I would say that I prefer the generatePassword version than the alternative which doesn't appear to be as secure/safe at first glance.

@arnydo
Copy link
Author

arnydo commented Sep 30, 2020

@alexellis I agree, generatePassword would be ideal since it is already available. However, since it is not a feature of the Core versions of PowerShell it seems that it would be best to provide a like alternative. If you look at the source code for generatePassword the alternative is basically doing the same thing. https://github.com/microsoft/referencesource/blob/f461f1986ca4027720656a0c77bede9963e20b7e/System.Web/Security/Membership.cs#L302

@alexellis
Copy link
Member

The powershell script has been removed, please use arkade instead, or helm and Git Bash.

@alexellis
Copy link
Member

/lock: resolved

@derek derek bot locked and limited conversation to collaborators Feb 24, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants