public static async Task <IReadOnlyList <string> > GetLetsEncryptHostNames(IAzureWebAppEnvironment webAppEnvironment, bool staging)
        {
            Site site;

            using (var client = await ArmHelper.GetWebSiteManagementClient(webAppEnvironment))
            {
                Trace.TraceInformation(
                    "Getting Web App '{0}' (slot '{1}') from resource group '{2}'",
                    webAppEnvironment.WebAppName,
                    webAppEnvironment.SiteSlotName,
                    webAppEnvironment.ResourceGroupName);

                site = client.WebApps.GetSiteOrSlot(webAppEnvironment.ResourceGroupName, webAppEnvironment.WebAppName, webAppEnvironment.SiteSlotName);
            }

            using (var httpClient = await ArmHelper.GetHttpClient(webAppEnvironment))
            {
                var certRequestUri = $"/subscriptions/{webAppEnvironment.SubscriptionId}/providers/Microsoft.Web/certificates?api-version=2016-03-01";
                Trace.TraceInformation("GET {0}", certRequestUri);
                var response = await ArmHelper.ExponentialBackoff().ExecuteAsync(async() => await httpClient.GetAsync(certRequestUri));

                Trace.TraceInformation("Reading ARM certificate query response");
                var body = await response.EnsureSuccessStatusCode().Content.ReadAsStringAsync();

                var letsEncryptCerts = ExtractCertificates(body).Where(s => s.Issuer.Contains(staging ? "Fake LE" : "Let's Encrypt"));

                var leCertThumbprints = new HashSet <string>(letsEncryptCerts.Select(c => c.Thumbprint));
                return(site.HostNameSslStates.Where(ssl => leCertThumbprints.Contains(ssl.Thumbprint)).Select(ssl => ssl.Name).ToArray());
            }
        }
Example #2
0
        public async Task RetryTest()
        {
            var client = HttpClientFactory.Create(new HttpClientHandler(), new TimeoutHandler());

            var retry = ArmHelper.ExponentialBackoff();
            var resp  = await retry.ExecuteAsync(async() =>
            {
                return(await client.PostAsJsonAsync("https://en8zkq5hogjyi.x.pipedream.net", new { text = "hello" }));
            });
        }
Example #3
0
        public async Task Install(ICertificateInstallModel model)
        {
            var cert = model.CertificateInfo;
            using (var webSiteClient = await ArmHelper.GetWebSiteManagementClient(azureEnvironment))
            {

                var s = webSiteClient.WebApps.GetSiteOrSlot(azureEnvironment.ResourceGroupName, azureEnvironment.WebAppName, azureEnvironment.SiteSlotName);

                Trace.TraceInformation(String.Format("Installing certificate {0} on azure with server farm id {1}", cert.Name, s.ServerFarmId));
                var newCert = new Certificate(s.Location, cert.Password, name: model.Host + "-" + cert.Certificate.Thumbprint, pfxBlob: cert.PfxCertificate, serverFarmId: s.ServerFarmId);
                //BUG https://github.com/sjkp/letsencrypt-siteextension/issues/99
                //using this will not install the certificate with the correct webSpace property set, 
                //and the app service will be unable to find the certificate if the app service plan has been moved between resource groups.
                //webSiteClient.Certificates.CreateOrUpdate(azureEnvironment.ServicePlanResourceGroupName, cert.Certificate.Subject.Replace("CN=", ""), newCert);

                var client = await ArmHelper.GetHttpClient(azureEnvironment);

                var body = JsonConvert.SerializeObject(newCert, JsonHelper.DefaultSerializationSettings);

                var retryPolicy = ArmHelper.ExponentialBackoff();

                var t = await retryPolicy.ExecuteAsync(async () =>
                {
                     return await client.PutAsync($"/subscriptions/{azureEnvironment.SubscriptionId}/resourceGroups/{azureEnvironment.ServicePlanResourceGroupName}/providers/Microsoft.Web/certificates/{newCert.Name}?api-version=2016-03-01", new StringContent(body, Encoding.UTF8, "application/json"));                    
                });
                Trace.TraceInformation(await t.Content.ReadAsStringAsync());
                t.EnsureSuccessStatusCode();

                foreach (var dnsName in model.AllDnsIdentifiers)
                {
                    var sslState = s.HostNameSslStates.FirstOrDefault(g => g.Name == dnsName);

                    if (sslState == null)
                    {
                        sslState = new HostNameSslState()
                        {
                            Name = dnsName,
                            SslState = settings.UseIPBasedSSL ? SslState.IpBasedEnabled : SslState.SniEnabled,
                        };
                        s.HostNameSslStates.Add(sslState);
                    }
                    else
                    {
                        //First time setting the HostNameSslState it is set to disabled.
                        sslState.SslState = settings.UseIPBasedSSL ? SslState.IpBasedEnabled : SslState.SniEnabled;
                    }
                    sslState.ToUpdate = true;
                    sslState.Thumbprint = cert.Certificate.Thumbprint;
                }
                webSiteClient.WebApps.BeginCreateOrUpdateSiteOrSlot(azureEnvironment.ResourceGroupName, azureEnvironment.WebAppName, azureEnvironment.SiteSlotName, s);
            }


        }        
        public static async Task<IReadOnlyList<string>> GetNonExpiringLetsEncryptHostNames(IAzureWebAppEnvironment webAppEnvironment, bool staging, int renewXNumberOfDaysBeforeExpiration)
        {
            Site site;
            using (var client = await ArmHelper.GetWebSiteManagementClient(webAppEnvironment).ConfigureAwait(false))
            {
                var webAppName = webAppEnvironment.WebAppName;
                var resourceGroupName = webAppEnvironment.ResourceGroupName;
                var siteSlotName = webAppEnvironment.SiteSlotName;
                Trace.TraceInformation(
                    "Getting Web App '{0}' (slot '{1}') from resource group '{2}'",
                    webAppName,
                    siteSlotName,
                    resourceGroupName);

                site = client.WebApps.GetSiteOrSlot(resourceGroupName, webAppName, siteSlotName);
                if (site == null)
                {
                    throw new InvalidOperationException(
                        $"Could not find web app '{webAppName}' (slot '{siteSlotName}') under Resource Groups '{resourceGroupName}'");
                }
            }

            using (var httpClient = await ArmHelper.GetHttpClient(webAppEnvironment).ConfigureAwait(false))
            {
                var certRequestUri = $"/subscriptions/{webAppEnvironment.SubscriptionId}/providers/Microsoft.Web/certificates?api-version=2016-03-01";
                Trace.TraceInformation("GET {0}", certRequestUri);
                var response = await ArmHelper.ExponentialBackoff().ExecuteAsync(() => httpClient.GetAsync(new Uri(certRequestUri, UriKind.Relative))).ConfigureAwait(false);

                Trace.TraceInformation("Reading ARM certificate query response");
                var body = await response.EnsureSuccessStatusCode().Content.ReadAsStringAsync().ConfigureAwait(false);

                var letsEncryptIssuerNames = staging ? s_letsEncrypStagingtIssuerNames : s_letsEncryptIssuerNames;

                var letsEncryptNonExpiringCerts = ExtractCertificates(body).Where(cert =>
                    letsEncryptIssuerNames.Contains(cert.Issuer) &&
                    cert.ExpirationDate > DateTime.UtcNow.AddDays(renewXNumberOfDaysBeforeExpiration));

                var letsEncryptNonExpiringThumbprints = new HashSet<string>(letsEncryptNonExpiringCerts.Select(c => c.Thumbprint));
                return site.HostNameSslStates.Where(ssl => letsEncryptNonExpiringThumbprints.Contains(ssl.Thumbprint)).Select(ssl => ssl.Name).ToArray();
            }
        }