174 lines
6.6 KiB
C#
174 lines
6.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Net;
|
|
using System.Web;
|
|
using Umbraco.Core;
|
|
using Umbraco.Core.IO;
|
|
using Umbraco.Core.Services;
|
|
using Umbraco.Web.HealthCheck.Checks.Config;
|
|
|
|
namespace Umbraco.Web.HealthCheck.Checks.Security
|
|
{
|
|
[HealthCheck(
|
|
"EB66BB3B-1BCD-4314-9531-9DA2C1D6D9A7",
|
|
"HTTPS Configuration",
|
|
Description = "Checks if your site is configured to work over HTTPS and if the Umbraco related configuration for that is correct.",
|
|
Group = "Security")]
|
|
public class HttpsCheck : HealthCheck
|
|
{
|
|
private readonly ILocalizedTextService _textService;
|
|
private readonly IRuntimeState _runtime;
|
|
|
|
private const string FixHttpsSettingAction = "fixHttpsSetting";
|
|
|
|
public HttpsCheck(ILocalizedTextService textService, IRuntimeState runtime)
|
|
{
|
|
_textService = textService;
|
|
_runtime = runtime;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get the status for this health check
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public override IEnumerable<HealthCheckStatus> GetStatus()
|
|
{
|
|
//return the statuses
|
|
return new[] { CheckIfCurrentSchemeIsHttps(), CheckHttpsConfigurationSetting(), CheckForValidCertificate() };
|
|
}
|
|
|
|
/// <summary>
|
|
/// Executes the action and returns it's status
|
|
/// </summary>
|
|
/// <param name="action"></param>
|
|
/// <returns></returns>
|
|
public override HealthCheckStatus ExecuteAction(HealthCheckAction action)
|
|
{
|
|
switch (action.Alias)
|
|
{
|
|
case FixHttpsSettingAction:
|
|
return FixHttpsSetting();
|
|
default:
|
|
throw new InvalidOperationException("HttpsCheck action requested is either not executable or does not exist");
|
|
}
|
|
}
|
|
|
|
private HealthCheckStatus CheckForValidCertificate()
|
|
{
|
|
var message = string.Empty;
|
|
var success = false;
|
|
var url = _runtime.ApplicationUrl;
|
|
|
|
// Attempt to access the site over HTTPS to see if it HTTPS is supported
|
|
// and a valid certificate has been configured
|
|
var address = string.Format("https://{0}:{1}", url.Host.ToLower(), url.Port);
|
|
var request = (HttpWebRequest)WebRequest.Create(address);
|
|
request.Method = "HEAD";
|
|
|
|
try
|
|
{
|
|
var response = (HttpWebResponse)request.GetResponse();
|
|
success = response.StatusCode == HttpStatusCode.OK;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
var exception = ex as WebException;
|
|
if (exception != null)
|
|
{
|
|
message = exception.Status == WebExceptionStatus.TrustFailure
|
|
? _textService.Localize("healthcheck/httpsCheckInvalidCertificate", new [] { exception.Message })
|
|
: _textService.Localize("healthcheck/httpsCheckInvalidUrl", new [] { address, exception.Message });
|
|
}
|
|
else
|
|
{
|
|
message = _textService.Localize("healthcheck/httpsCheckInvalidUrl", new[] { address, ex.Message });
|
|
}
|
|
}
|
|
|
|
var actions = new List<HealthCheckAction>();
|
|
|
|
if (success)
|
|
message = _textService.Localize("healthcheck/httpsCheckValidCertificate");
|
|
|
|
return
|
|
new HealthCheckStatus(message)
|
|
{
|
|
ResultType = success ? StatusResultType.Success : StatusResultType.Error,
|
|
Actions = actions
|
|
};
|
|
}
|
|
|
|
private HealthCheckStatus CheckIfCurrentSchemeIsHttps()
|
|
{
|
|
var uri = HttpContext.Current.Request.Url;
|
|
var success = uri.Scheme == "https";
|
|
|
|
var actions = new List<HealthCheckAction>();
|
|
|
|
return
|
|
new HealthCheckStatus(_textService.Localize("healthcheck/httpsCheckIsCurrentSchemeHttps", new[] { success ? string.Empty : "not" }))
|
|
{
|
|
ResultType = success ? StatusResultType.Success : StatusResultType.Error,
|
|
Actions = actions
|
|
};
|
|
}
|
|
|
|
private HealthCheckStatus CheckHttpsConfigurationSetting()
|
|
{
|
|
var httpsSettingEnabled = Core.Configuration.GlobalSettings.UseSSL;
|
|
var uri = HttpContext.Current.Request.Url;
|
|
var actions = new List<HealthCheckAction>();
|
|
|
|
string resultMessage;
|
|
StatusResultType resultType;
|
|
if (uri.Scheme != "https")
|
|
{
|
|
resultMessage = _textService.Localize("healthcheck/httpsCheckConfigurationRectifyNotPossible");
|
|
resultType = StatusResultType.Info;
|
|
}
|
|
else
|
|
{
|
|
if (httpsSettingEnabled == false)
|
|
actions.Add(new HealthCheckAction(FixHttpsSettingAction, Id)
|
|
{
|
|
Name = _textService.Localize("healthcheck/httpsCheckEnableHttpsButton"),
|
|
Description = _textService.Localize("healthcheck/httpsCheckEnableHttpsDescription")
|
|
});
|
|
|
|
resultMessage = _textService.Localize("healthcheck/httpsCheckConfigurationCheckResult",
|
|
new[] {httpsSettingEnabled.ToString(), httpsSettingEnabled ? string.Empty : "not"});
|
|
resultType = httpsSettingEnabled ? StatusResultType.Success: StatusResultType.Error;
|
|
}
|
|
|
|
return
|
|
new HealthCheckStatus(resultMessage)
|
|
{
|
|
ResultType = resultType,
|
|
Actions = actions
|
|
};
|
|
}
|
|
|
|
private HealthCheckStatus FixHttpsSetting()
|
|
{
|
|
var configFile = IOHelper.MapPath("~/Web.config");
|
|
const string xPath = "/configuration/appSettings/add[@key='umbracoUseSSL']/@value";
|
|
var configurationService = new ConfigurationService(configFile, xPath);
|
|
var updateConfigFile = configurationService.UpdateConfigFile("true");
|
|
|
|
if (updateConfigFile.Success)
|
|
{
|
|
return
|
|
new HealthCheckStatus(_textService.Localize("healthcheck/httpsCheckEnableHttpsSuccess"))
|
|
{
|
|
ResultType = StatusResultType.Success
|
|
};
|
|
}
|
|
|
|
return
|
|
new HealthCheckStatus(_textService.Localize("healthcheck/httpsCheckEnableHttpsError", new [] { updateConfigFile.Result }))
|
|
{
|
|
ResultType = StatusResultType.Error
|
|
};
|
|
}
|
|
}
|
|
} |