Skip to content

Commit 916b471

Browse files
authored
Make localhost certificate longer listed, warn about machine reboot (#10413)
1 parent def05bc commit 916b471

1 file changed

Lines changed: 63 additions & 56 deletions

File tree

tools/Setup-DevEnvironment.ps1

Lines changed: 63 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,124 +1,131 @@
11
param([string]$SiteName = "NuGet Gallery", [string]$SitePhysicalPath, [string]$AppCmdPath)
22

3-
function Get-SiteFQDN() {return "localhost"} # DevSkim: ignore DS162092
4-
function Get-SiteHttpHost() {return "$(Get-SiteFQDN):80"}
5-
function Get-SiteHttpsHost() {return "$(Get-SiteFQDN):443"}
3+
function Get-SiteFQDN() { return "localhost" } # DevSkim: ignore DS162092
4+
function Get-SiteHttpHost() { return "$(Get-SiteFQDN):80" }
5+
function Get-SiteHttpsHost() { return "$(Get-SiteFQDN):443" }
66

77
function Get-SiteCertificate() {
8-
return @(dir -l "Cert:\LocalMachine\Root" `
9-
| where {$_.Subject -eq "CN=$(Get-SiteFQDN)"}) `
8+
$cert = @(Get-ChildItem -l "Cert:\LocalMachine\Root" `
9+
| Where-Object { $_.Subject -eq "CN=$(Get-SiteFQDN)" }) `
10+
| Sort-Object -Property NotAfter -Descending `
1011
| Select-Object -First 1
11-
}
12-
13-
function Initialize-SiteCertificate() {
14-
Write-Host "Generating a Self-Signed SSL Certificate for $(Get-SiteFQDN)"
1512

16-
# Create a new self-signed certificate. New-SelfSignedCertificate can only create
17-
# certificates into the My certificate store.
18-
$myCert = New-SelfSignedCertificate -DnsName $(Get-SiteFQDN) -CertStoreLocation "Cert:\LocalMachine\My"
13+
if (($null -ne $cert) -and ($cert.NotAfter -lt (Get-Date))) {
14+
Write-Host "Site certificate is expired. Recreating it. If you encounter issues, restart your computer." -ForegroundColor Yellow
15+
$cert = $null
16+
}
1917

20-
# Move the newly created self-signed certificate to the Root store.
21-
$rootStore = New-Object System.Security.Cryptography.X509Certificates.X509Store("Root", "LocalMachine")
22-
$rootStore.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)
23-
$rootStore.Add($myCert)
24-
$rootStore.Close()
25-
26-
# Return the self-signed certificate from the Root store.
27-
$cert = Get-SiteCertificate
28-
29-
if($cert -eq $null) {
30-
throw "Failed to create an SSL Certificate"
18+
if ($null -eq $cert) {
19+
Write-Host "Generating a self-signed SSL certificate for $(Get-SiteFQDN)"
20+
21+
# Create a new self-signed certificate. New-SelfSignedCertificate can only create
22+
# certificates into the My certificate store.
23+
$newCert = New-SelfSignedCertificate -DnsName $(Get-SiteFQDN) -CertStoreLocation "Cert:\LocalMachine\My" -NotAfter (Get-Date).AddYears(10)
24+
25+
# Move the newly created self-signed certificate to the Root store.
26+
$rootStore = New-Object System.Security.Cryptography.X509Certificates.X509Store("Root", "LocalMachine")
27+
$rootStore.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)
28+
$rootStore.Add($newCert)
29+
$rootStore.Close()
30+
31+
# Return the self-signed certificate from the Root store.
32+
$cert = @(Get-ChildItem -l "Cert:\LocalMachine\Root" `
33+
| Where-Object { $_.Thumbprint -eq $newCert.Thumbprint }) `
34+
| Select-Object -First 1
35+
if ($null -eq $cert) {
36+
throw "Failed to create an SSL certificate"
37+
}
3138
}
3239

3340
return $cert
3441
}
3542

3643
function Invoke-Netsh() {
3744
$argStr = $([String]::Join(" ", $args))
38-
$result = netsh @args
45+
$result = (netsh @args | Out-String).Trim()
3946
$parsed = [Regex]::Match($result, ".*Error: (\d+).*")
4047

41-
if($parsed.Success) {
48+
if ($parsed.Success) {
4249
$err = $parsed.Groups[1].Value
43-
if($err -ne "183") {
50+
if (($err -ne "183") -and ($err -ne "2")) {
4451
throw $result
4552
}
46-
} elseif ($result -eq "The parameter is incorrect.") {
53+
}
54+
elseif ($result -eq "The parameter is incorrect.") {
4755
throw "Parameters for netsh are incorrect:`r`n $argStr"
48-
} else {
56+
}
57+
else {
4958
Write-Host $result
5059
}
5160
}
5261

53-
if(!(([Security.Principal.WindowsPrincipal]([System.Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole([Security.Principal.WindowsBuiltInRole]"Administrator"))) {
62+
if (!(([Security.Principal.WindowsPrincipal]([System.Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole([Security.Principal.WindowsBuiltInRole]"Administrator"))) {
5463
throw "This script must be run as an admin."
5564
}
5665

5766
Write-Host "[BEGIN] Setting up IIS Express" -ForegroundColor Cyan
5867

5968
$ScriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Path
60-
if(!$SitePhysicalPath) {
69+
if (!$SitePhysicalPath) {
6170
$SitePhysicalPath = Join-Path $ScriptRoot "..\src\NuGetGallery"
6271
}
63-
if(!(Test-Path $SitePhysicalPath)) {
72+
if (!(Test-Path $SitePhysicalPath)) {
6473
throw "Could not find site at $SitePhysicalPath. Use -SitePhysicalPath argument to specify the path."
6574
}
6675
$SitePhysicalPath = Convert-Path $SitePhysicalPath
6776

6877
# Find IIS Express
69-
if(!$AppCmdPath) {
70-
$IISXVersion = dir 'HKLM:\Software\Microsoft\IISExpress' |
71-
foreach { New-Object System.Version ($_.PSChildName) } |
72-
sort -desc |
73-
select -first 1
74-
if(!$IISXVersion) {
78+
if (!$AppCmdPath) {
79+
$IISXVersion = Get-ChildItem 'HKLM:\Software\Microsoft\IISExpress' |
80+
ForEach-Object { New-Object System.Version ($_.PSChildName) } |
81+
Sort-Object -desc |
82+
Select-Object -first 1
83+
if (!$IISXVersion) {
7584
throw "Could not find IIS Express. Please install IIS Express before running this script, or use -AppCmdPath to specify the path to appcmd.exe for your IIS environment"
7685
}
7786
$IISRegKey = (Get-ItemProperty "HKLM:\Software\Microsoft\IISExpress\$IISXVersion")
7887
$IISExpressDir = $IISRegKey.InstallPath
79-
if(!(Test-Path $IISExpressDir)) {
88+
if (!(Test-Path $IISExpressDir)) {
8089
throw "Can't find IIS Express in $IISExpressDir. Please install IIS Express"
8190
}
8291
$AppCmdPath = "$IISExpressDir\appcmd.exe"
8392
}
8493

85-
if(!(Test-Path $AppCmdPath)) {
94+
if (!(Test-Path $AppCmdPath)) {
8695
throw "Could not find appcmd.exe in $AppCmdPath!"
8796
}
8897

8998
# Enable access to the necessary URLs
9099
# S-1-1-0 is the unlocalized version for: user=Everyone
100+
Invoke-Netsh http delete urlacl "url=http://$(Get-SiteHttpHost)/"
101+
Invoke-Netsh http delete urlacl "url=https://$(Get-SiteHttpsHost)/"
91102
Invoke-Netsh http add urlacl "url=http://$(Get-SiteHttpHost)/" "sddl=D:(A;;GX;;;S-1-1-0)" # DevSkim: ignore DS137138
92103
Invoke-Netsh http add urlacl "url=https://$(Get-SiteHttpsHost)/" "sddl=D:(A;;GX;;;S-1-1-0)"
93104

94105
$SiteFullName = "$SiteName ($(Get-SiteFQDN))"
95106

96-
$sites = @(&$AppCmdPath list site $SiteFullName)
97-
if($sites.Length -gt 0) {
107+
$sites = @(& $AppCmdPath list site $SiteFullName)
108+
if ($sites.Length -gt 0) {
98109
Write-Warning "Site '$SiteFullName' already exists. Deleting and recreating."
99-
&$AppCmdPath delete site "$SiteFullName"
110+
& $AppCmdPath delete site "$SiteFullName"
100111
}
101112

102-
&$AppCmdPath add site /name:"$SiteFullName" /bindings:"http://$(Get-SiteHttpHost),https://$(Get-SiteHttpsHost)" /physicalPath:$SitePhysicalPath # DevSkim: ignore DS137138
113+
& $AppCmdPath add site /name:"$SiteFullName" /bindings:"http://$(Get-SiteHttpHost),https://$(Get-SiteHttpsHost)" /physicalPath:$SitePhysicalPath # DevSkim: ignore DS137138
103114

104115
Write-Host "[DONE] Setting up IIS Express" -ForegroundColor Cyan
105-
Write-Host "[BEGIN] Setting SSL Certificate" -ForegroundColor Cyan
106-
107-
# Ensure a certificate is bound to localhost's port 443. Generate a new
108-
# self-signed certificate if necessary.
109-
$siteCert = Get-SiteCertificate
110116

111-
if ($siteCert -eq $null) {
112-
$siteCert = Initialize-SiteCertificate
113-
}
117+
Write-Host "[BEGIN] Setting up SSL certificate" -ForegroundColor Cyan
114118

119+
$siteCert = Get-SiteCertificate
115120
Write-Host "Using SSL Certificate: $($siteCert.Thumbprint)"
116-
121+
Invoke-Netsh http delete sslcert ipport="0.0.0.0:443"
122+
Invoke-Netsh http delete sslcert hostnameport="$(Get-SiteHttpsHost)"
117123
Invoke-Netsh http add sslcert hostnameport="$(Get-SiteHttpsHost)" certhash="$($siteCert.Thumbprint)" certstorename=Root appid="{$([Guid]::NewGuid().ToString())}"
118124

119-
Write-Host "[DONE] Setting SSL Certificate" -ForegroundColor Cyan
120-
Write-Host "[BEGIN] Running Migrations" -ForegroundColor Cyan
125+
Write-Host "[DONE] Setting up SSL certificate" -ForegroundColor Cyan
126+
127+
Write-Host "[BEGIN] Running Entity Framework migrations" -ForegroundColor Cyan
121128

122-
& "$ScriptRoot\Update-Databases.ps1" -MigrationTargets NuGetGallery,NuGetGallerySupportRequest -NuGetGallerySitePath $SitePhysicalPath
129+
& "$ScriptRoot\Update-Databases.ps1" -MigrationTargets NuGetGallery, NuGetGallerySupportRequest -NuGetGallerySitePath $SitePhysicalPath
123130

124-
Write-Host "[DONE] Running Migrations" -ForegroundColor Cyan
131+
Write-Host "[DONE] Running Entity Framework migrations" -ForegroundColor Cyan

0 commit comments

Comments
 (0)