Browse Source

Configurable certificate verification

This commit introduces the `certificate_verification` property:

```xml
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="certificate_verification"
         value="C:\apps\OhmGraphite\influxdb-selfsigned.crt" />
   </appSettings>
</configuration>
```

The possible values:

 - True (the default): all certificates are verified
 - False: No certificates are verified (INSECURE)
 - a file path of a certificate that the server is allowed to return and
 still be considered a valid request (useful for self signed
 certificates). Recommended to be an absolute file path.

The nice thing about targeting .net 5 is that reading of pem
certificates is baked in (as well as other formats), so one can take the
output from an openssl command and copy the file here.

The downside of this commit is that it does now include more code so
that the executable is larger (33MB to 39MB) and it takes about that
much RAM as well.
Nick Babcock 4 năm trước cách đây
mục cha
commit
d10b6a7343

+ 17 - 0
OhmGraphite.Test/ConfigTest.cs

@@ -1,5 +1,6 @@
 using System;
 using System.Configuration;
+using System.Net;
 using Xunit;
 
 namespace OhmGraphite.Test
@@ -124,5 +125,21 @@ namespace OhmGraphite.Test
             Assert.True(results.IsHidden("/amdcpu/0/load/2"));
             Assert.False(results.IsHidden("/amdcpu/0/load/3"));
         }
+
+        [Fact]
+        public void CanInstallCertificateVerification()
+        {
+            var current = ServicePointManager.ServerCertificateValidationCallback;
+            MetricConfig.InstallCertificateVerification("true");
+            Assert.Equal(current, ServicePointManager.ServerCertificateValidationCallback);
+
+            MetricConfig.InstallCertificateVerification("false");
+            Assert.NotEqual(current, ServicePointManager.ServerCertificateValidationCallback);
+
+            MetricConfig.InstallCertificateVerification("assets/influxdb-selfsigned.crt");
+            Assert.NotEqual(current, ServicePointManager.ServerCertificateValidationCallback);
+
+            ServicePointManager.ServerCertificateValidationCallback = null;
+        }
     }
 }

+ 1 - 0
OhmGraphite.Test/OhmGraphite.Test.csproj

@@ -27,6 +27,7 @@
     <None Include="..\assets\static-name.config" Link="assets/static-name.config" CopyToOutputDirectory="PreserveNewest" />
     <None Include="..\assets\rename.config" Link="assets/rename.config" CopyToOutputDirectory="PreserveNewest" />
     <None Include="..\assets\hidden-sensors.config" Link="assets/hidden-sensors.config" CopyToOutputDirectory="PreserveNewest" />
+    <None Include="..\assets\influxdb-selfsigned.crt" Link="assets/influxdb-selfsigned.crt" CopyToOutputDirectory="PreserveNewest" />
 
     <None Include="..\ci\timescale.dockerfile" Link="docker/timescale.dockerfile" CopyToOutputDirectory="PreserveNewest" />
     <None Include="..\ci\setup-docker.sh" Link="docker/ci/setup-docker.sh" CopyToOutputDirectory="PreserveNewest" />

+ 29 - 0
OhmGraphite/MetricConfig.cs

@@ -1,6 +1,9 @@
 using System;
 using System.Collections.Generic;
 using System.Linq;
+using System.Net;
+using System.Net.Security;
+using System.Security.Cryptography.X509Certificates;
 
 namespace OhmGraphite
 {
@@ -42,6 +45,7 @@ namespace OhmGraphite
             var interval = TimeSpan.FromSeconds(seconds);
 
             INameResolution nameLookup = NameLookup(config["name_lookup"] ?? "netbios");
+            InstallCertificateVerification(config["certificate_verification"] ?? "True");
 
             var type = config["type"] ?? "graphite";
             GraphiteConfig gconfig = null;
@@ -99,6 +103,31 @@ namespace OhmGraphite
             }
         }
 
+        public static void InstallCertificateVerification(string type)
+        {
+            switch (type.ToLowerInvariant())
+            {
+                // Do not change default .net behavior when given True
+                case "true":
+                    break;
+
+                // Do not verify certificate
+                case "false":
+                    ServicePointManager.ServerCertificateValidationCallback =
+                        (sender, certificate, chain, errors) => true;
+                    break;
+
+                // Else assume that it points to a file path of a self signed
+                // certificate that we will check against
+                default:
+                    var cert = new X509Certificate2(type);
+                    ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, errors) =>
+                        errors == SslPolicyErrors.None ||
+                        string.Equals(cert.Thumbprint, certificate.GetCertHashString(), StringComparison.InvariantCultureIgnoreCase);
+                    break;
+            }
+        }
+
         public bool TryGetAlias(string v, out string alias) => Aliases.TryGetValue(v, out alias);
         public bool IsHidden(string id) => HiddenSensors.Contains(id);
     }

+ 21 - 0
assets/influxdb-selfsigned.crt

@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIIDazCCAlOgAwIBAgIUOwfYKJuZntSJzuXrLLOtEfZDAWMwDQYJKoZIhvcNAQEL
+BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
+GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMTA1MTExMTQ0NTNaFw0yMjA1
+MTExMTQ0NTNaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw
+HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQCmHBIE8C55XfvFTDH2UXOdx+DnG7Rb1fiJEKGNI66h
+gts52qPzcebFn+9+RAGNeNoHdbDpSbO6rSti/hOqmO5GD0xfoBPq9LkgVA7LJ6ra
+KRhRNTrBAZUX+zaDVu76PDbWHGuvV1ZBTUJtdW86lL9rsfdcdU2n/AjsvbmsC/Qx
+jv8l7d7d7YS9jAHSqviKHG59JQOmA+Tf0bAnkKHP9YDJNrPJiEic/QFL0V22x6hH
+nIAQ2+zL1pNUtrZnp7qxbvk9SVJnN7opVDd/tuGBd19EEjdZXyYcoqOITmT65hFj
+EN8UHSzRpVTrRJ7EQDFLERje74b33UmPe0kRV/1QiIODAgMBAAGjUzBRMB0GA1Ud
+DgQWBBQGg6ysOo7cYg9Wx5iUxHjx3iEBTzAfBgNVHSMEGDAWgBQGg6ysOo7cYg9W
+x5iUxHjx3iEBTzAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBJ
+kqd/NwVm7EtWq0rgpuBNmPTNLgb4r35N5COnrFq1A/Zh7TN5OVHMUAtiKq5l4RTg
+v+YbQP5044Z9atokOpbS8i+KYvm96jLTnH/G3Bm/ddK5MlpNVn4SuN/YeysBnZMn
+rta4bGzunAmPbbuY6QNkBzM3WqrKzH0LDcEtnBGlmFo611DWqCpsKECgzxB39as6
+YehVol+UN1lIFYCNtzNyiomg69Bh/VGmC6rdRI8H6jEAaOUMR5SNXwKHA7pOs0i0
+Kilt9kGE3uCcHMUUJLBzKHQQ0ppRjLFtdzVXIs8F/u9QxXsDx/xP90TdhvCJm6K3
+AUct5nBqD0C5i125dw4J
+-----END CERTIFICATE-----