Skip to content

Conversation

@rjmholt
Copy link
Collaborator

@rjmholt rjmholt commented Sep 26, 2018

PR Summary

Adds a dependency on the newly published SelfSignedCertificate module so that we can construct our own self-signed certificates at test time rather than checking them in.

To do this, the following happens:

  • Publish-PSTestTools will Save-Module the SelfSignedCertificate from the gallery to
    $RepoRoot/test/tools/Modules/
  • In WebListener.psm1 we import the SelfSignedCertificate module
    • I tried both using module at the top of the psm1 and NestedModules in the psd1 here but neither seemed to work
  • Start-WebListener now builds both client and server certificates when it is called

PR Checklist

.gitignore Outdated
/staging/
/Packages/
*.nuget.props
/test/tools/Modules/SelfSignedCertificate/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even though this module is for test, perhaps it's ok to just use install-module -scope currentuser? Adding it to a repo path breaks our work towards separating tests from dependencies on the repo.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had that exact discussion with @JamesWTruher and argued that we shouldn't pollute the installed modules because PowerShell was build on a machine. But I will make the change

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should not be polluting the user's space with anything that isn't explicitly testing our behavior for the current user. These tests are very likely to be run on a dev box and we should not be adding stuff to the current user's scope. Further, this is a tool only for our tests. If the user happens to have this already, it still shouldn't use it, we should be using the module that we know we should be using in the location that we control without molesting their environment.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather put it into a temp folder then

.gitignore Outdated
*.AppImage

# Ignore certificates
*.pfx
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly, the pfx files should be generated outside of the repo structure

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The question is where. We don't have a cross-platform temp dir and I would very much prefer not to put it in $HOME. Ideally it would be on the $TestDrive, but anything that tries to operate across Describe blocks with a generated certificate will fail.

Arguably we should refactor things to do exactly that, but I think that is out of scope of this PR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For now, Path::GetTempPath() is good enough I think

{
param([string]$CertificatePath)

$password = ConvertTo-SecureString -Force -AsPlainText 'password'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't have a hardcoded password. Looks like the GeneratePassword() method isn't available in corefx. I think it's fine to generate a random alphanumeric password.

$initTimeoutSeconds = 15
$appDll = 'WebListener.dll'
$serverPfx = 'ServerCert.pfx'
$serverPfxPassword = 'password'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe be better to store in env var the generated password rather than hardcode

@rjmholt rjmholt force-pushed the remove-web-cmdlet-test-certs branch from 07044ee to 89e27c7 Compare September 27, 2018 04:01
@iSazonov
Copy link
Collaborator

We slow down CIs. Why we need the change?

@SteveL-MSFT
Copy link
Member

@iSazonov as a Microsoft project, we can't have secrets (even test secrets) stored statically in the repo

@SteveL-MSFT
Copy link
Member

@rjmholt the test failures are related to this PR

@rjmholt
Copy link
Collaborator Author

rjmholt commented Sep 27, 2018

@SteveL-MSFT Yes I just fixed them 🤞

@rjmholt rjmholt force-pushed the remove-web-cmdlet-test-certs branch from 72256f8 to 70c01d0 Compare September 27, 2018 17:24
Copy link
Collaborator

@iSazonov iSazonov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@SteveL-MSFT I found some samples of hard coded passwords in test files by key "password". (And in New-TestHost too).

build.psm1 Outdated

# Path to a directory to store modules we temporarily need to test PowerShell
$script:TestModuleDirPath = Join-Path ([System.IO.Path]::GetTempPath()) 'PwshTestModules'
New-Item -Force -ItemType Directory -Path $script:TestModuleDirPath
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need output to console? If no we should New-Item > $null.

build.psm1 Outdated

# Autoload (in subprocess) temporary modules used in our tests
$command += '$env:PSModulePath = '+"'$TestModulePath$TestModulePathSeparator'" + '+$($env:PSModulePath);'
$command += '$env:PSModulePath = '+"'$TestModulePath$TestModulePathSeparator$script:TestModuleDirPath$TestModulePathSeparator'" + '+$env:PSModulePath;'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm afraid of such expressions. Maybe use Join-Path before the line?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Join-Path won't work since we want ; and not \ (or : and not / on *nix). But I'll break this expression up a bit

@rjmholt rjmholt assigned rjmholt and adityapatwardhan and unassigned rjmholt Sep 28, 2018

# Hackery to create a new 10 digit random hex string as a password
$rand = [Random]::new()
$global:protectedCertPassword = ConvertTo-SecureString -Force -AsPlainText (((1..10).ForEach{ '{0:x}' -f $rand.Next(0xf) }) -join '')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better expose it through a function, instead of a global variable. The global variable will linger around even after you remove the module from a session.


$random = [Random]::new()

return ((1..$Length).ForEach{ '{0:x}' -f $random.Next(0xf) }) -join ''
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code is the same as New-CertificatePassword can we re-use the code?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a common module I could put the function to generate a password in that is imported in both the web cmdlet tests and the CmdMessage tests?

Right now the only common module I can think of is the SelfSignedCertificate module, but that's not part of this codebase

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants