Private/AdfsProxyHealthChecks.ps1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
Function TestIsAdfsProxyRunning
{
    $testName = "TestIsAdfsProxyRunning";
    $serviceStateOutputKey = "ADFSProxyServiceState";
    $testResult = New-Object TestResult -ArgumentList($testName);

    try
    {
        $adfsProxyServiceState = Get-ServiceState($adfsProxyServiceName);
        if ($adfsProxyServiceState -ne "Running")
        {
            $testResult.Result = [ResultType]::Fail;
            $testResult.Detail = "Current state of $adfsProxyServiceName is: $adfsProxyServiceState";
        }
        $testResult.Output = @{$serviceStateOutputKey = $adfsProxyServiceState};

        return $testResult;
    }
    catch [Exception]
    {
        return Create-ErrorExceptionTestResult $testName $_.Exception
    }
}

Function TestSTSReachableFromProxy()
{
    $testName = "STSReachableFromProxy"
    $exceptionKey = "STSReachableFromProxyException"
    try
    {
        $mexUrlTestResult = New-Object TestResult -ArgumentList($testName);
        $mexUrlTestResult.Output = @{$exceptionKey = "NONE"}

        $proxyInfo = gwmi -Class ProxyService -Namespace root\ADFS

        $stsHost = $proxyInfo.HostName + ":" + $proxyInfo.HostHttpsPort

        $mexUrl = "https://" + $stsHost + "/adfs/services/trust/mex";
        $webClient = New-Object net.WebClient;
        try
        {
            $data = $webClient.DownloadData($mexUrl);
            #If the mex is successfully downloaded from proxy, then the test is deemed succesful
        }
        catch [Net.WebException]
        {
            $exceptionEncoded = [System.Web.HttpUtility]::HtmlEncode($_.Exception.ToString());
            $mexUrlTestResult.Result = [ResultType]::Fail;
            $mexUrlTestResult.Detail = $exceptionEncoded;
            $mexUrlTestResult.Output.Set_Item($exceptionKey, $exceptionEncoded)
        }

        return $mexUrlTestResult;
    }
    catch [Exception]
    {
        return Create-ErrorExceptionTestResult $testName $_.Exception
    }
}

Function TestNoNonSelfSignedCertificatesInRootStore
{
    $testName = "TestNoNonSelfSignedCertificateInRootStore";
    $testResult = New-Object TestResult -ArgumentList($testName)
    $certificateOutputKey = "NonSelfSignedCertificates";

    try
    {
        $nonSelfSignedCertificates = Get-ChildItem Cert:\LocalMachine\root -Recurse | Where-Object {$_.Issuer -ne $_.Subject} | Select-Object FriendlyName, Issuer, Subject, Thumbprint;

        if ($nonSelfSignedCertificates.Count -ne 0)
        {
            $testResult.Detail = "There were non-self-signed certificates found in the root store. Move them to the intermediate store.";
            $testResult.Result = [ResultType]::Fail;
            $testResult.Output = @{$certificateOutputKey = $nonSelfSignedCertificates};
        }

        return $testResult;
    }
    catch [Exception]
    {
        return Create-ErrorExceptionTestResult $testName $_.Exception
    }
}

Function TestProxySslBindings
{
    Param(
        [Parameter(Mandatory = $true)]
        [string]
        $AdfsSslThumbprint
    )
    $testName = "TestProxySslBindings";
    $testResult = New-Object TestResult -ArgumentList($testName);
    Out-Verbose "Parameter AdfsSslThumbprint = $AdfsSslThumbprint";

    try
    {
        $bindings = GetSslBindings;
        Out-Verbose "Attempting to get federation service name.";
        $proxyInfo = Get-WmiObject -Class ProxyService -Namespace root\ADFS

        $federationServiceName = $proxyInfo.HostName;
        Out-Verbose "Retrieved federation service name: $federationServiceName.";

        $adfsPort = $proxyInfo.HostHttpsPort;
        $tlsPort = $proxyInfo.TlsClientPort;
        Out-Verbose "Retrieved ADFS Port: $adfsPort TLS Port: $tlsPort";

        $erroneousBindings = @{}

        # Expected SSL bindings
        Out-Verbose "Attempting to validate expected SSL bindings."
        $ret = IsSslBindingValid -Bindings $bindings -BindingIpPortOrHostnamePort $($federationServiceName + ":" + $adfsPort) -CertificateThumbprint $AdfsSslThumbprint
        if (!($ret.IsValid))
        {
            $erroneousBindings[$($federationServiceName + ":" + $adfsPort)] = $ret["Detail"];
        }

        $bindings.Remove($($federationServiceName + ":" + $adfsPort));

        $ret = IsSslBindingValid -Bindings $bindings -BindingIpPortOrHostnamePort $($federationServiceName + ":" + $tlsPort) -CertificateThumbprint $AdfsSslThumbprint -VerifyCtlStoreName $false;
        if (!($ret.IsValid))
        {
            $erroneousBindings[$($federationServiceName + ":" + $tlsPort)] = $ret["Detail"];
        }

        $bindings.Remove($($federationServiceName + ":" + $tlsPort));

        # Check custom bindings that match the AD FS Application Id
        foreach ($key in $bindings.Keys)
        {
            if ($bindings[$key]["Application ID"] -eq $adfsApplicationId)
            {
                Out-Verbose "Checking custom SSL certificate binding $key.";

                # We can only validate the Thumbprint here since we do not know which ip/hostname port this binding is for.
                $ret = IsSslBindingValid -Bindings $bindings -BindingIpPortOrHostnamePort $key -CertificateThumbprint $AdfsSslThumbprint -VerifyCtlStoreName $false;
                if (!($ret.IsValid))
                {
                    $erroneousBindings[$key] = $ret["Detail"];
                }
            }
        }

        if ($erroneousBindings.Count -ne 0)
        {
            $testResult.Result = [ResultType]::Fail;
            $testResult.Detail = "There were SSL bindings found that were incorrect. Check the output for more detail.";
            $testResult.Output = @{"ErroneousBindings" = $erroneousBindings};
        }

        return $testResult;
    }
    catch [Exception]
    {
        return Create-ErrorExceptionTestResult $testName $_.Exception
    }
}