From a37acc90eb40f5544cd5a1dffe36434c4dc4d3ab Mon Sep 17 00:00:00 2001 From: Adrien Ferrand Date: Tue, 11 Feb 2020 16:13:27 +0100 Subject: [PATCH] Continue configuration --- .../test_main.py | 77 ++++++++++++------- windows-installer/auto-update.ps1 | 48 +++++++----- 2 files changed, 78 insertions(+), 47 deletions(-) diff --git a/certbot-ci/windows_installer_integration_tests/test_main.py b/certbot-ci/windows_installer_integration_tests/test_main.py index 047491159..ab08d07f8 100644 --- a/certbot-ci/windows_installer_integration_tests/test_main.py +++ b/certbot-ci/windows_installer_integration_tests/test_main.py @@ -16,12 +16,35 @@ with warnings.catch_warnings(): warnings.simplefilter("ignore") import pkg_resources +SCHEDULED_TASK_NAME = 'Certbot Renew & Auto-Update Task' + @pytest.fixture -def installer(request): +def signing_cert(): + cert_thumbprint = None + try: + pfx_file = pkg_resources.resource_filename('windows_installer_integration_tests', 'assets/test-signing.pfx') + output = _ps('(Import-PfxCertificate -FilePath {0} -CertStoreLocation Cert:\\LocalMachine\\Root).Thumbprint' + .format(pfx_file), capture_stdout=True) + cert_thumbprint = output.strip() + if not cert_thumbprint: + raise RuntimeError('Error, test signing certificate could not be installed.') + + yield pfx_file + finally: + if cert_thumbprint: + _ps('Get-ChildItem Cert:\\LocalMachine\\Root\\{0} | Remove-Item'.format(cert_thumbprint)) + + +@pytest.fixture +def installer(request, signing_cert): with tempfile.TemporaryDirectory() as temp_dir: shutil.copy(request.config.option.installer_path, temp_dir) - yield os.path.join(temp_dir, os.path.basename(request.config.option.installer_path)) + installer_path = os.path.join(temp_dir, os.path.basename(request.config.option.installer_path)) + _ps('Set-AuthenticodeSignature -FilePath {0} -Certificate (Get-PfxCertificate -FilePath {1}) | Out-Null' + .format(installer_path, signing_cert)) + + yield installer_path @pytest.fixture @@ -32,16 +55,20 @@ def github_mock(installer): pass class GitHubMock(BaseHTTPRequestHandler): + # def log_message(self, log_format, *args): + # pass + def do_GET(self): - if re.match(r'^.*/release/latest$', self.path): + if re.match(r'^.*/releases/latest$', self.path): self.send_response(200) self.send_header('Content-type', 'application/json') self.end_headers() self.wfile.write(json.dumps( { + 'tag_name': 'v99.9.9', 'assets': [{ 'name': os.path.basename(installer), - 'browser_download_url': 'https://localhost/{0}'.format(os.path.basename(installer)) + 'browser_download_url': 'http://localhost:8009/{0}'.format(os.path.basename(installer)) }] } ).encode()) @@ -61,36 +88,33 @@ def github_mock(installer): thread.daemon = True thread.start() - yield True + yield 'http://localhost:8009/releases/latest' finally: if server: server.shutdown() server.server_close() -@pytest.fixture -def signing_cert(): - cert_thumbprint = None +@pytest.fixture(autouse=True) +def registry_config(signing_cert, github_mock): try: - pfx_file = pkg_resources.resource_filename('windows_installer_integration_tests', 'assets/test-signing.pfx') - output = _ps('(Import-PfxCertificate -FilePath {0} -CertStoreLocation Cert:\\LocalMachine\\Root).Thumbprint' - .format(pfx_file), capture_stdout=True) - cert_thumbprint = output.strip() - if not cert_thumbprint: - raise RuntimeError('Error, test signing certificate could not be installed.') - yield pfx_file + _ps('New-Item -Path HKLM:\\Software -Name Certbot -ErrorAction SilentlyContinue | Out-Null; exit 0') + _ps('New-ItemProperty -Path HKLM:\\Software\\Certbot -Name CertbotUpgradeApiURL -Value {} ' + '| Out-Null'.format(github_mock)) + _ps('New-ItemProperty -Path HKLM:\\Software\\Certbot -Name CertbotSigningPubKey -Value ' + '([Convert]::ToBase64String((Get-PfxCertificate -FilePath {0}).GetPublicKey())) ' + '| Out-Null'.format(signing_cert)) + + yield finally: - if cert_thumbprint: - _ps('Get-ChildItem Cert:\\LocalMachine\\Root\\{0} | Remove-Item'.format(cert_thumbprint)) + _ps('Remove-ItemProperty -Path HKLM:\\Software\\Certbot -Name CertbotUpgradeApiURL') + _ps('Remove-ItemProperty -Path HKLM:\\Software\\Certbot -Name CertbotSigningPubKey') @unittest.skipIf(os.name != 'nt', reason='Windows installer tests must be run on Windows.') -def test_it(github_mock, installer, signing_cert): - assert github_mock - assert signing_cert - +def test_it(installer): try: - subprocess.check_call(['certbot', '--version']) + subprocess.check_call('certbot --version', shell=True) except (subprocess.CalledProcessError, OSError): pass else: @@ -101,20 +125,21 @@ def test_it(github_mock, installer, signing_cert): subprocess.check_call([installer, '/S']) # Assert certbot is installed and runnable - output = subprocess.check_output(['certbot', '--version'], universal_newlines=True) + output = subprocess.check_output('certbot --version', shell=True, universal_newlines=True) assert re.match(r'^certbot \d+\.\d+\.\d+.*$', output), 'Flag --version does not output a version.' # Assert renew task is installed and ready - output = _ps('(Get-ScheduledTask -TaskName "Certbot Renew Task").State', capture_stdout=True) + output = _ps('(Get-ScheduledTask -TaskName "{}").State'.format(SCHEDULED_TASK_NAME), capture_stdout=True) assert output.strip() == 'Ready' # Assert renew task is working now = time.time() - _ps('Start-ScheduledTask -TaskName "Certbot Renew Task"') + _ps('Start-ScheduledTask -TaskName "{}"'.format(SCHEDULED_TASK_NAME)) status = 'Running' while status != 'Ready': - status = _ps('(Get-ScheduledTask -TaskName "Certbot Renew Task").State', capture_stdout=True).strip() + status = _ps('(Get-ScheduledTask -TaskName "{}").State' + .format(SCHEDULED_TASK_NAME), capture_stdout=True).strip() time.sleep(1) log_path = os.path.join('C:\\', 'Certbot', 'log', 'letsencrypt.log') diff --git a/windows-installer/auto-update.ps1 b/windows-installer/auto-update.ps1 index 902a861c4..a47f8b13b 100644 --- a/windows-installer/auto-update.ps1 +++ b/windows-installer/auto-update.ps1 @@ -20,10 +20,10 @@ process { $installDir = $PSScriptRoot - if (Test-Path env:CERTBOT_PUBLIC_KEY) { - $certbotPublicKey = $env:CERTBOT_PUBLIC_KEY + if ((Test-Path HKLM:\Software\Certbot) -And ((Get-ItemProperty -Path HKLM:\Software\Certbot).PSObject.Properties.Name -Contains "CertbotSigningPubKey")) { + $certbotSigningPubKey = (Get-ItemProperty -Path HKLM:\Software\Certbot).CertbotSigningPubKey } else { - $certbotPublicKey = ' + $certbotSigningPubKey = ' -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6MR8W/galdxnpGqBsYbq OzQb2eyW15YFjDDEMI0ZOzt8f504obNs920lDnpPD2/KqgsfjOgw2K7xWDJIj/18 @@ -36,10 +36,10 @@ CQIDAQAB ' } - if (Test-Path env:CERTBOT_UPGRADE_API) { - $certbotUpgradeApi = $env:CERTBOT_UPGRADE_API + if ((Test-Path HKLM:\Software\Certbot) -And ((Get-ItemProperty -Path HKLM:\Software\Certbot).PSObject.Properties.Name -Contains "CertbotUpgradeApiURL")) { + $certbotUpgradeApiURL = (Get-ItemProperty -Path HKLM:\Software\Certbot).CertbotUpgradeApiURL } else { - $certbotUpgradeApi = 'https://api.github.com/repos/certbot/certbot/releases/latest' + $certbotUpgradeApiURL = 'https://api.github.com/repos/certbot/certbot/releases/latest' } # Get current local certbot version @@ -59,7 +59,7 @@ Assuming Certbot is not up-to-date. # Get latest remote certbot version try { [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 - $result = Invoke-RestMethod -Uri $certbotUpgradeApi + $result = Invoke-RestMethod -Uri $certbotUpgradeApiURL $latestVersion = $result.tag_name -replace '^v(\d+\.\d+\.\d+).*$', '$1' $latestVersion = [System.Version]"$latestVersion" } catch { @@ -97,30 +97,36 @@ Aborting auto-upgrade process. # Check installer has a valid signature from the Certbot release team $signature = Get-AuthenticodeSignature $installerPath - # Uncomment the following lines of code once the Certbot installer is correctly signed. - # if ($signature.Status -ne 'Valid') { - # throw "Downloaded installer has no or invalid Authenticode signature." - # } - # $publicKey = $certbotPublicKey -replace '-+.*-+' -replace "`n" -replace "`r" - # $refBinaryPublicKey = [System.Convert]::FromBase64String($publicKey) - # $curBinaryPublicKey = $signature.SignerCertificate.PublicKey.EncodedKeyValue.RawData - # $diff = Compare-Object -ReferenceObject $refBinaryPublicKey -DifferenceObject $curBinaryPublicKey - # if ($diff) { - # throw "Downloaded installer has not been signed by Certbot development team." - # } +# # Uncomment the following lines of code once the Certbot installer is correctly signed. +# if ($signature.Status -ne 'Valid') { +# throw "Downloaded installer has no or invalid Authenticode signature." +# } +# $publicKey = $certbotSigningPubKey -replace '-+.*-+' -replace "`n" -replace "`r" +# $refBinaryPublicKey = [System.Convert]::FromBase64String($publicKey) +# $curBinaryPublicKey = $signature.SignerCertificate.PublicKey.EncodedKeyValue.RawData +# $diff = Compare-Object -ReferenceObject $refBinaryPublicKey -DifferenceObject $curBinaryPublicKey +# if ($diff) { +# throw "Downloaded installer has not been signed by Certbot development team." +# } if (Test-Path $installDir\uninstall.exe) { # Uninstall old Certbot first Write-Message "Running the uninstaller for old version (install dir: $installDir) ..." - # Start-Process -FilePath $installDir\uninstall.exe -ArgumentList "/S _?=$installDir" + Start-Process -FilePath $installDir\uninstall.exe -ArgumentList "/S _?=$installDir" } # Install new version of Certbot Write-Message "Running the installer for new version (install dir: $installDir) ..." - # Start-Process -FilePath $installerPath -ArgumentList "/S /D=$installDir" + Start-Process -FilePath $installerPath -ArgumentList "/S /D=$installDir" Write-Message "Certbot $latestVersion is installed." + } catch { + Write-Error @" +Could not update to the latest remote certbot version. Error was: +$_ +Aborting auto-upgrade process. +"@ } finally { - # Remove-Item $installerPath -ErrorAction 'Ignore' + Remove-Item $installerPath -ErrorAction 'Ignore' } }