Skip to content

Commit

Permalink
Badgerati#573: refactor the cert logic, and fix build script
Browse files Browse the repository at this point in the history
  • Loading branch information
Badgerati committed Jun 13, 2020
1 parent d4f1555 commit 4493094
Show file tree
Hide file tree
Showing 10 changed files with 211 additions and 143 deletions.
21 changes: 16 additions & 5 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ The following is a set of guidelines for contributing to Pode on GitHub. These a
* [Issues](#issues)
* [Branch Names](#branch-names)
* [Pull Requests](#pull-requests)
* [Building](#building)
* [Testing](#testing)
* [Documentation](#documentation)
* [Styleguide](#styleguide)
Expand All @@ -38,7 +39,9 @@ If you have a question, feel free to either ask it on [GitHub Issues](https://gi

## About Pode

Pode is a PowerShell framework, and the aim is to make it purely PowerShell only with *no* external dependencies. This allows Pode to be very lightweight, and just work out-of-the-box when the module is installed on any platform.
Pode is a PowerShell framework/web server. The aim is to make it purely PowerShell, with *no* external dependencies - other than what is available in .NET Core. This allows Pode to be very lightweight, and just work out-of-the-box when the module is installed on any platform.

The only current exception to the "all PowerShell" rule is the socket listener Pode uses. This listener is apart of Pode, but is written in .NET Core.

## How to Contribute

Expand All @@ -65,15 +68,23 @@ When you open a new Pull Request, please ensure:

Once opened GitHub will automatically run CI on Windows, Linux and MacOS, as well as Code Coverage.

### Building

Before running any of Pode's examples, you will need to compile the Listener first. To do so you will need [`Invoke-Build`](https://github.com/nightroman/Invoke-Build). Once installed, run the following:

```powershell
Invoke-Build Build
```

### Testing

Pode has Unit Tests, there are also some Performance Tests but you do not need to worry about them. There are also currently no Integration Tests.
Pode has Unit and Integration Tests, there are also some Performance Tests but you do not need to worry about them.

Where possible, please try to create/update new Unit Tests especially for features. Don't worry too much about decreasing the Code Coverage.
Where possible, please try to create/update new Unit/Integration Tests especially for features. Don't worry too much about decreasing the Code Coverage.

The Unit Tests can be found at `/tests/unit/` from the root of the repository.
The Unit Tests can be found at `/tests/unit/` from the root of the repository, and the Integration Tests can be found at `tests/integration`.

To run the tests, you will need [`Invoke-Build`](https://github.com/nightroman/Invoke-Build). Once installed, run the following to run the tests:
To run the tests, you will need [`Invoke-Build`](https://github.com/nightroman/Invoke-Build) (running the tests will compile Pode's listener). Once installed, run the following to run the tests:

```powershell
Invoke-Build Test
Expand Down
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,16 @@ docker pull badgerati/pode
Pull Requests, Bug Reports and Feature Requests are welcome! Feel free to help out with Issues and Projects!

To run the unit tests, run the following command from the root of the repository (this will auto-install Pester for you):
To run the unit tests, run the following command from the root of the repository (this will build Pode and, if needed, auto-install Pester/.NET Core):

```powershell
Invoke-Build Test
```

To just build Pode, before running any examples, run the following:

```powershell
Invoke-Build Build
```

To work on issues you can fork Pode, and then open a Pull Request for approval. Pull Requests should be made against the `develop` branch. Each Pull Request should also have an appropriate issue created.
4 changes: 2 additions & 2 deletions docs/Getting-Started/Migrating/1X-to-2X.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ If you were previously specifying `-Type Pode` on your [`Start-PodeServer`], the

### Endpoints

With the dropping of HttpListener, the old `-Certificate` is now the old `-CertificateFile` parameter. The `-RawCertificate` is now `-X509Certificate`.
With the dropping of HttpListener, the old `-Certificate` is now the old `-CertificateFile` parameter. The `-RawCertificate` parameter is now called `-X509Certificate`.

`-CertificateThumbprint` has also been removed.
`-CertificateThumbprint` remains the same, and only works on Windows.
29 changes: 20 additions & 9 deletions docs/Tutorials/Certificates.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,33 @@

Pode has the ability to generate and bind self-signed certificates (for dev/testing), as well as the ability to bind existing certificates for HTTPS.

There are 4 ways to setup HTTPS on [`Add-PodeEndpoint`](../../Functions/Core/Add-PodeEndpoint):
There are 5 ways to setup HTTPS on [`Add-PodeEndpoint`](../../Functions/Core/Add-PodeEndpoint):

1. Supplying just the `-Certificate`, such as a `.cer`.
2. Supplying both the `-Certificate` and `-CertificatePassword`, such as for `.pfx`.
3. Supplying `-X509Certificate` of type `X509Certificate`.
4. Supplying the `-SelfSigned` switch, to generate a quick self-signed `X509Certificate`.
3. Supplying a `-CertificateThumbprint` for a certificate installed at `Cert:\CurrentUser\My` on Windows.
4. Supplying `-X509Certificate` of type `X509Certificate`.
5. Supplying the `-SelfSigned` switch, to generate a quick self-signed `X509Certificate`.

## Usage

### Self-Signed
### File

If you are developing/testing a site on HTTPS then Pode can generate and bind quick self-signed certificates. To do this you can pass the `-SelfSigned` switch:
To bind a certificate file, you use the `-Certificate` parameter, along with the `-CertificatePassword` parameter for `.pfx` certificates. The following example supplies some `.pfx` to enable HTTPS support:

```powershell
Start-PodeServer {
Add-PodeEndpoint -Address * -Port 8443 -Protocol Https -SelfSigned
Add-PodeEndpoint -Address * -Port 8090 -Protocol Https -Certificate './cert.pfx' -CertificatePassword 'Hunter2'
}
```

### File
### Thumbprint

To bind a certificate file, you use the `-Certificate` parameter, along with the `-CertificatePassword` parameter for `.pfx` certificates. The following example supplies some `.pfx` to enable HTTPS support:
On Windows only, you can use a certificate that is installed at `Cert:\CurrentUser\My` using its thumbprint:

```powershell
Start-PodeServer {
Add-PodeEndpoint -Address * -Port 8090 -Protocol Https -Certificate './cert.pfx' -CertificatePassword 'Hunter2'
Add-PodeEndpoint -Address * -Port 8090 -Protocol Https -CertificateThumbprint '2A623A8DC46ED42A13B27DD045BFC91FDDAEB957'
}
```

Expand All @@ -40,6 +41,16 @@ $cert = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new('.
Add-PodeEndpoint -Address * -Port 8443 -Protocol Https -X509Certificate $cert
```

### Self-Signed

If you are developing/testing a site on HTTPS then Pode can generate and bind quick self-signed certificates. To do this you can pass the `-SelfSigned` switch:

```powershell
Start-PodeServer {
Add-PodeEndpoint -Address * -Port 8443 -Protocol Https -SelfSigned
}
```

## SSL Protocols

The default allowed SSL protocols are SSL3 and TLS1.2, but you can change these to any of: SSL2, SSL3, TLS, TLS11, TLS12, TLS13. This is specified in your `server.psd1` configuration file:
Expand Down
1 change: 1 addition & 0 deletions examples/web-pages-https.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Start-PodeServer {

# bind to ip/port and set as https with self-signed cert
Add-PodeEndpoint -Address * -Port 8443 -Protocol Https -SelfSigned
#Add-PodeEndpoint -Address * -Port 8443 -Protocol Https -CertificateThumbprint '2A623A8DC46ED42A13B27DD045BFC91FDDAEB957'

# set view engine for web pages
Set-PodeViewEngine -Type Pode
Expand Down
15 changes: 9 additions & 6 deletions packers/choco/tools/ChocolateyInstall.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,16 @@ function Install-PodeModule($path, $version)
{
Push-Location (Join-Path $env:ChocolateyPackageFolder 'src')

New-Item -ItemType Directory -Path (Join-Path $path 'Private') -Force | Out-Null
New-Item -ItemType Directory -Path (Join-Path $path 'Public') -Force | Out-Null
New-Item -ItemType Directory -Path (Join-Path $path 'Misc') -Force | Out-Null
# which folders do we need?
$folders = @('Private', 'Public', 'Misc', 'Libs')

Copy-Item -Path ./Private/* -Destination (Join-Path $path 'Private') -Force | Out-Null
Copy-Item -Path ./Public/* -Destination (Join-Path $path 'Public') -Force | Out-Null
Copy-Item -Path ./Misc/* -Destination (Join-Path $path 'Misc') -Force | Out-Null
# create the directories, then copy the source
$folders | ForEach-Object {
New-Item -ItemType Directory -Path (Join-Path $path $_) -Force | Out-Null
Copy-Item -Path "./$($_)/*" -Destination (Join-Path $path $_) -Force | Out-Null
}

# copy general files
Copy-Item -Path ./Pode.psm1 -Destination $path -Force | Out-Null
Copy-Item -Path ./Pode.psd1 -Destination $path -Force | Out-Null
Copy-Item -Path ./LICENSE.txt -Destination $path -Force | Out-Null
Expand Down
14 changes: 11 additions & 3 deletions pode.build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ $Versions = @{
MkDocs = '1.1.2'
PSCoveralls = '1.0.0'
SevenZip = '18.5.0.20180730'
DotNetCore = '3.1.5'
Checksum = '0.2.0'
MkDocsTheme = '5.2.1'
PlatyPS = '0.14.0'
Expand Down Expand Up @@ -142,14 +143,21 @@ task PackDeps -If (Test-PodeBuildIsWindows) ChocoDeps, {
}
}

# Synopsis: Install dependencies for compiling/building
task BuildDeps {
# install dotnet
if (!(Test-PodeBuildCommand 'dotnet')) {
Invoke-PodeBuildInstall 'dotnetcore' $Versions.DotNetCore
}
}

# Synopsis: Install dependencies for running tests
task TestDeps {
# install pester
Install-PodeBuildModule Pester

# install PSCoveralls
if (Test-PodeBuildCanCodeCoverage)
{
if (Test-PodeBuildCanCodeCoverage) {
Install-PodeBuildModule PSCoveralls
}
}
Expand All @@ -176,7 +184,7 @@ task DocsDeps ChocoDeps, {
#>

# Synopsis: Build the .NET Core Listener
task Build {
task Build BuildDeps, {
if (Test-Path ./src/Libs) {
Remove-Item -Path ./src/Libs -Recurse -Force | Out-Null
}
Expand Down
63 changes: 0 additions & 63 deletions src/Private/Helpers.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -147,69 +147,6 @@ function Test-IsAdminUser
}
}

function New-PodeSelfSignedCertificate
{
$sanBuilder = [System.Security.Cryptography.X509Certificates.SubjectAlternativeNameBuilder]::new()
$sanBuilder.AddIpAddress([ipaddress]::Loopback) | Out-Null
$sanBuilder.AddIpAddress([ipaddress]::IPv6Loopback) | Out-Null
$sanBuilder.AddDnsName('localhost') | Out-Null

if (![string]::IsNullOrWhiteSpace($env:COMPUTERNAME)) {
$sanBuilder.AddDnsName($env:COMPUTERNAME) | Out-Null
}

$rsa = [System.Security.Cryptography.RSA]::Create(2048)
$distinguishedName = [X500DistinguishedName]::new("CN=localhost")

$req = [System.Security.Cryptography.X509Certificates.CertificateRequest]::new(
$distinguishedName,
$rsa,
[System.Security.Cryptography.HashAlgorithmName]::SHA256,
[System.Security.Cryptography.RSASignaturePadding]::Pkcs1
)

$flags = (
[System.Security.Cryptography.X509Certificates.X509KeyUsageFlags]::DataEncipherment -bor
[System.Security.Cryptography.X509Certificates.X509KeyUsageFlags]::KeyEncipherment -bor
[System.Security.Cryptography.X509Certificates.X509KeyUsageFlags]::DigitalSignature
)

$req.CertificateExtensions.Add(
[System.Security.Cryptography.X509Certificates.X509KeyUsageExtension]::new(
$flags,
$false
)
) | Out-Null

$oid = [System.Security.Cryptography.OidCollection]::new()
$oid.Add([System.Security.Cryptography.Oid]::new('1.3.6.1.5.5.7.3.1')) | Out-Null

$req.CertificateExtensions.Add(
[System.Security.Cryptography.X509Certificates.X509EnhancedKeyUsageExtension]::new(
$oid,
$false
)
)

$req.CertificateExtensions.Add($sanBuilder.Build()) | Out-Null

$cert = $req.CreateSelfSigned(
[System.DateTimeOffset]::UtcNow.AddDays(-1),
[System.DateTimeOffset]::UtcNow.AddYears(10)
)

if (Test-IsWindows) {
$cert.FriendlyName = 'localhost'
}

$cert = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new(
$cert.Export([System.Security.Cryptography.X509Certificates.X509ContentType]::Pfx, 'self-signed'),
'self-signed'
)

return $cert
}

function Get-PodeHostIPRegex
{
param (
Expand Down
Loading

0 comments on commit 4493094

Please sign in to comment.