зеркало из https://github.com/SteeltoeOSS/Common.git
Merge branch 'dev'
This commit is contained in:
Коммит
bbd6b12877
14
Common.sln
14
Common.sln
|
@ -37,6 +37,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Steeltoe.Common.Test", "tes
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Steeltoe.Common.Net", "src\Steeltoe.Common.Net\Steeltoe.Common.Net.csproj", "{5C2D53DB-2980-4393-BCA1-B4C51004E4F7}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Steeltoe.Common.Security", "src\Steeltoe.Common.Security\Steeltoe.Common.Security.csproj", "{8D322AD5-ED49-4D40-952C-B38FD97D21EF}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Steeltoe.Common.Security.Test", "test\Steeltoe.Common.Security.Test\Steeltoe.Common.Security.Test.csproj", "{6E2CBAC4-3FF1-4DC9-9B9B-D0ADFE80218D}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -71,6 +75,14 @@ Global
|
|||
{5C2D53DB-2980-4393-BCA1-B4C51004E4F7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{5C2D53DB-2980-4393-BCA1-B4C51004E4F7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{5C2D53DB-2980-4393-BCA1-B4C51004E4F7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8D322AD5-ED49-4D40-952C-B38FD97D21EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8D322AD5-ED49-4D40-952C-B38FD97D21EF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8D322AD5-ED49-4D40-952C-B38FD97D21EF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8D322AD5-ED49-4D40-952C-B38FD97D21EF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{6E2CBAC4-3FF1-4DC9-9B9B-D0ADFE80218D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{6E2CBAC4-3FF1-4DC9-9B9B-D0ADFE80218D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6E2CBAC4-3FF1-4DC9-9B9B-D0ADFE80218D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6E2CBAC4-3FF1-4DC9-9B9B-D0ADFE80218D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -83,6 +95,8 @@ Global
|
|||
{7FF75564-423A-4EE6-B7AD-9D35C428757F} = {CC77ED1F-BC03-4B9D-A07A-186C9A13042B}
|
||||
{101DF01E-FDE9-4B97-9666-C3777CC308D0} = {CC77ED1F-BC03-4B9D-A07A-186C9A13042B}
|
||||
{5C2D53DB-2980-4393-BCA1-B4C51004E4F7} = {D9798FDE-76F4-4848-8AE0-95249C0101F0}
|
||||
{8D322AD5-ED49-4D40-952C-B38FD97D21EF} = {D9798FDE-76F4-4848-8AE0-95249C0101F0}
|
||||
{6E2CBAC4-3FF1-4DC9-9B9B-D0ADFE80218D} = {CC77ED1F-BC03-4B9D-A07A-186C9A13042B}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {4A85F9DA-2C2D-48E9-A28C-9B35C473C150}
|
||||
|
|
Двоичные данные
config/versions-dev.props
Двоичные данные
config/versions-dev.props
Двоичный файл не отображается.
|
@ -0,0 +1,25 @@
|
|||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
|
||||
namespace Steeltoe.Common.Security
|
||||
{
|
||||
public class CertificateOptions : ICertificateOptions
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
public X509Certificate2 Certificate { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
|
||||
namespace Steeltoe.Common.Security
|
||||
{
|
||||
public interface ICertificateOptions
|
||||
{
|
||||
string Name { get; }
|
||||
|
||||
X509Certificate2 Certificate { get; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Steeltoe.Common.Security
|
||||
{
|
||||
public class PemCertificateProvider : ConfigurationProvider
|
||||
{
|
||||
private IConfigurationRoot _certFileProvider;
|
||||
private IConfigurationRoot _keyFileProvider;
|
||||
|
||||
public PemCertificateProvider(IConfigurationRoot certFileProvider, IConfigurationRoot keyFileProvider)
|
||||
{
|
||||
_certFileProvider = certFileProvider;
|
||||
_keyFileProvider = keyFileProvider;
|
||||
_certFileProvider.GetReloadToken().RegisterChangeCallback(NotifyCertChanged, null);
|
||||
_keyFileProvider.GetReloadToken().RegisterChangeCallback(NotifyKeyChanged, null);
|
||||
}
|
||||
|
||||
public override void Load()
|
||||
{
|
||||
}
|
||||
|
||||
public override void Set(string key, string value)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
public override bool TryGet(string key, out string value)
|
||||
{
|
||||
value = _certFileProvider[key];
|
||||
if (!string.IsNullOrEmpty(value))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
value = _keyFileProvider[key];
|
||||
if (!string.IsNullOrEmpty(value))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override IEnumerable<string> GetChildKeys(IEnumerable<string> earlierKeys, string parentPath)
|
||||
{
|
||||
return base.GetChildKeys(earlierKeys, parentPath);
|
||||
}
|
||||
|
||||
private void NotifyCertChanged(object state)
|
||||
{
|
||||
OnReload();
|
||||
_certFileProvider.GetReloadToken().RegisterChangeCallback(NotifyCertChanged, null);
|
||||
}
|
||||
|
||||
private void NotifyKeyChanged(object state)
|
||||
{
|
||||
OnReload();
|
||||
_keyFileProvider.GetReloadToken().RegisterChangeCallback(NotifyKeyChanged, null);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System.IO;
|
||||
|
||||
namespace Steeltoe.Common.Security
|
||||
{
|
||||
public class PemCertificateSource : IConfigurationSource
|
||||
{
|
||||
private string _certFilePath;
|
||||
private string _keyFilePath;
|
||||
|
||||
public PemCertificateSource(string certFilePath, string keyFilePath)
|
||||
{
|
||||
_certFilePath = Path.GetFullPath(certFilePath);
|
||||
_keyFilePath = Path.GetFullPath(keyFilePath);
|
||||
}
|
||||
|
||||
public IConfigurationProvider Build(IConfigurationBuilder builder)
|
||||
{
|
||||
var certSource = new FileSource("certificate")
|
||||
{
|
||||
FileProvider = null,
|
||||
Path = Path.GetFileName(_certFilePath),
|
||||
Optional = false,
|
||||
ReloadOnChange = true,
|
||||
ReloadDelay = 1000
|
||||
};
|
||||
|
||||
var keySource = new FileSource("privateKey")
|
||||
{
|
||||
FileProvider = null,
|
||||
Path = Path.GetFileName(_keyFilePath),
|
||||
Optional = false,
|
||||
ReloadOnChange = true,
|
||||
ReloadDelay = 1000,
|
||||
};
|
||||
|
||||
var certProvider = new ConfigurationBuilder()
|
||||
.SetBasePath(Path.GetDirectoryName(_certFilePath))
|
||||
.Add(certSource)
|
||||
.Build();
|
||||
|
||||
var keyProvider = new ConfigurationBuilder()
|
||||
.SetBasePath(Path.GetDirectoryName(_keyFilePath))
|
||||
.Add(keySource)
|
||||
.Build();
|
||||
|
||||
return new PemCertificateProvider(certProvider, keyProvider);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning disable SA1402 // File may only contain a single class
|
||||
internal class FileSource : FileConfigurationSource
|
||||
{
|
||||
internal string Key { get; }
|
||||
|
||||
public FileSource(string key)
|
||||
: base()
|
||||
{
|
||||
Key = key;
|
||||
}
|
||||
|
||||
public override IConfigurationProvider Build(IConfigurationBuilder builder)
|
||||
{
|
||||
EnsureDefaults(builder);
|
||||
return new FileProvider(this);
|
||||
}
|
||||
}
|
||||
|
||||
internal class FileProvider : FileConfigurationProvider
|
||||
{
|
||||
public FileProvider(FileConfigurationSource source)
|
||||
: base(source)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Load(Stream stream)
|
||||
{
|
||||
var source = Source as FileSource;
|
||||
string key = source.Key;
|
||||
using (var reader = new StreamReader(stream))
|
||||
{
|
||||
string value = reader.ReadToEnd();
|
||||
Data[key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore SA1402 // File may only contain a single class
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.FileProviders;
|
||||
using System;
|
||||
|
||||
namespace Steeltoe.Common.Security
|
||||
{
|
||||
public static class PemConfigurationExtensions
|
||||
{
|
||||
public static IConfigurationBuilder AddPemFiles(this IConfigurationBuilder builder, string certFilePath, string keyFilePath)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(certFilePath))
|
||||
{
|
||||
throw new ArgumentException(nameof(certFilePath));
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(keyFilePath))
|
||||
{
|
||||
throw new ArgumentException(nameof(keyFilePath));
|
||||
}
|
||||
|
||||
builder.Add(new PemCertificateSource(certFilePath, keyFilePath));
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,130 @@
|
|||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.OpenSsl;
|
||||
using Org.BouncyCastle.Pkcs;
|
||||
using Org.BouncyCastle.Security;
|
||||
using Org.BouncyCastle.X509;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using MS = System.Security.Cryptography.X509Certificates;
|
||||
|
||||
namespace Steeltoe.Common.Security
|
||||
{
|
||||
public class PemConfigureCertificateOptions : IConfigureNamedOptions<CertificateOptions>
|
||||
{
|
||||
private IConfiguration _config;
|
||||
private ILogger _logger;
|
||||
|
||||
public PemConfigureCertificateOptions(IConfiguration config, ILogger logger = null)
|
||||
{
|
||||
if (config == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(config));
|
||||
}
|
||||
|
||||
_config = config;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public void Configure(string name, CertificateOptions options)
|
||||
{
|
||||
if (options == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(options));
|
||||
}
|
||||
|
||||
options.Name = name;
|
||||
|
||||
var pemCert = _config["certificate"];
|
||||
var pemKey = _config["privateKey"];
|
||||
|
||||
if (string.IsNullOrEmpty(pemCert) || string.IsNullOrEmpty(pemKey))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var certBytes = Encoding.Default.GetBytes(pemCert);
|
||||
var keyBytes = Encoding.Default.GetBytes(pemKey);
|
||||
|
||||
X509Certificate cert = ReadCertificate(certBytes);
|
||||
AsymmetricCipherKeyPair keys = ReadKeys(keyBytes);
|
||||
|
||||
var pfxBytes = CreatePfxContainer(cert, keys);
|
||||
options.Certificate = new MS.X509Certificate2(pfxBytes);
|
||||
}
|
||||
|
||||
public void Configure(CertificateOptions options)
|
||||
{
|
||||
Configure(Options.DefaultName, options);
|
||||
}
|
||||
|
||||
internal byte[] CreatePfxContainer(X509Certificate cert, AsymmetricCipherKeyPair keys)
|
||||
{
|
||||
var certEntry = new X509CertificateEntry(cert);
|
||||
|
||||
var pkcs12Store = new Pkcs12StoreBuilder()
|
||||
.SetUseDerEncoding(true)
|
||||
.Build();
|
||||
var keyEntry = new AsymmetricKeyEntry(keys.Private);
|
||||
pkcs12Store.SetKeyEntry("ServerInstance", keyEntry, new X509CertificateEntry[] { certEntry });
|
||||
|
||||
using (MemoryStream stream = new MemoryStream())
|
||||
{
|
||||
pkcs12Store.Save(stream, null, new SecureRandom());
|
||||
var bytes = stream.ToArray();
|
||||
return Pkcs12Utilities.ConvertToDefiniteLength(bytes);
|
||||
}
|
||||
}
|
||||
|
||||
internal AsymmetricCipherKeyPair ReadKeys(byte[] keyBytes)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var reader = new StreamReader(new MemoryStream(keyBytes)))
|
||||
{
|
||||
return new PemReader(reader).ReadObject() as AsymmetricCipherKeyPair;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger?.LogError(e, "Unable to read PEM encoded keys");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
internal X509Certificate ReadCertificate(byte[] certBytes)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var reader = new StreamReader(new MemoryStream(certBytes)))
|
||||
{
|
||||
return new PemReader(reader).ReadObject() as X509Certificate;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger?.LogError(e, "Unable to read PEM encoded certificate");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<Import Project="..\..\versions.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<Description>Steeltoe Common Security Library</Description>
|
||||
<VersionPrefix>$(SteeltoeVersion)</VersionPrefix>
|
||||
<VersionSuffix>$(VersionSuffix)</VersionSuffix>
|
||||
<Authors>Pivotal;dtillman</Authors>
|
||||
<!--<TargetFramework>netstandard2.0</TargetFramework>-->
|
||||
<TargetFrameworks>netstandard2.0</TargetFrameworks>
|
||||
<AssemblyName>Steeltoe.Common.Security</AssemblyName>
|
||||
<PackageId>Steeltoe.Common.Security</PackageId>
|
||||
<PackageTags>NET Core;NET Framework</PackageTags>
|
||||
<PackageIconUrl>https://steeltoe.io/images/transparent.png</PackageIconUrl>
|
||||
<PackageProjectUrl>https://steeltoe.io</PackageProjectUrl>
|
||||
<PackageLicenseUrl>http://www.apache.org/licenses/LICENSE-2.0</PackageLicenseUrl>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<DocumentationFile>bin\$(Configuration)\$(TargetFramework)\Steeltoe.Common.Security.xml</DocumentationFile>
|
||||
<NoWarn>SA1101;SA1124;SA1201;SA1309;SA1310;SA1401;SA1600;SA1652;1591</NoWarn>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Portable.BouncyCastle" Version="$(BouncyCastleVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options" Version="$(ExtensionsVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="$(ExtensionsVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="$(ExtensionsVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="$(ExtensionsVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="$(ExtensionsVersion)" />
|
||||
<PackageReference Include="StyleCop.Analyzers" Version="$(StyleCopVersion)">
|
||||
<PrivateAssets>All</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<AdditionalFiles Include="..\..\stylecop.json">
|
||||
<Link>stylecop.json</Link>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</AdditionalFiles>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -19,8 +19,21 @@ namespace Steeltoe.Common.LoadBalancer
|
|||
{
|
||||
public interface ILoadBalancer
|
||||
{
|
||||
/// <summary>
|
||||
/// Evaluates a Uri for a host name that can be resolved into a service instance
|
||||
/// </summary>
|
||||
/// <param name="request">A Uri containing a service name that can be resolved into one or more service instances</param>
|
||||
/// <returns>The original Uri, with serviceName replaced by the host:port of a service instance</returns>
|
||||
Task<Uri> ResolveServiceInstanceAsync(Uri request);
|
||||
|
||||
/// <summary>
|
||||
/// A mechanism for tracking statistics for service instances
|
||||
/// </summary>
|
||||
/// <param name="originalUri">The original request Uri</param>
|
||||
/// <param name="resolvedUri">The Uri resolved by the load balancer</param>
|
||||
/// <param name="responseTime">The amount of time taken for a remote call to complete</param>
|
||||
/// <param name="exception">Any exception called during calls to a resolved service instance</param>
|
||||
/// <returns>A task</returns>
|
||||
Task UpdateStatsAsync(Uri originalUri, Uri resolvedUri, TimeSpan responseTime, Exception exception);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
namespace Steeltoe.Common.Net
|
||||
{
|
||||
public class HostInfo
|
||||
{
|
||||
public string Hostname { get; set; }
|
||||
|
||||
public string IpAddress { get; set; }
|
||||
|
||||
public bool Override { get; set; }
|
||||
|
||||
public HostInfo()
|
||||
{
|
||||
}
|
||||
|
||||
public HostInfo(string hostname)
|
||||
{
|
||||
Hostname = hostname;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Steeltoe.Common.Net
|
||||
{
|
||||
public class InetOptions
|
||||
{
|
||||
public const string PREFIX = "spring:cloud:inet";
|
||||
|
||||
public string DefaultHostname { get; set; } = "localhost";
|
||||
|
||||
public string DefaultIpAddress { get; set; } = "127.0.0.1";
|
||||
|
||||
public string IgnoredInterfaces { get; set; }
|
||||
|
||||
public bool UseOnlySiteLocalInterfaces { get; set; } = false;
|
||||
|
||||
public string PreferredNetworks { get; set; }
|
||||
|
||||
internal IEnumerable<string> GetIgnoredInterfaces()
|
||||
{
|
||||
if (string.IsNullOrEmpty(IgnoredInterfaces))
|
||||
{
|
||||
return new List<string>();
|
||||
}
|
||||
|
||||
return IgnoredInterfaces.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
|
||||
internal IEnumerable<string> GetPreferredNetworks()
|
||||
{
|
||||
if (string.IsNullOrEmpty(PreferredNetworks))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return PreferredNetworks.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,269 @@
|
|||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Net.Sockets;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Steeltoe.Common.Net
|
||||
{
|
||||
public class InetUtils
|
||||
{
|
||||
private readonly InetOptions _options;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
public InetUtils(InetOptions options, ILogger logger = null)
|
||||
{
|
||||
_options = options;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public HostInfo FindFirstNonLoopbackHostInfo()
|
||||
{
|
||||
var address = FindFirstNonLoopbackAddress();
|
||||
if (address != null)
|
||||
{
|
||||
return ConvertAddress(address);
|
||||
}
|
||||
|
||||
HostInfo hostInfo = new HostInfo();
|
||||
hostInfo.Hostname = _options.DefaultHostname;
|
||||
hostInfo.IpAddress = _options.DefaultIpAddress;
|
||||
return hostInfo;
|
||||
}
|
||||
|
||||
public IPAddress FindFirstNonLoopbackAddress()
|
||||
{
|
||||
IPAddress result = null;
|
||||
try
|
||||
{
|
||||
int lowest = int.MaxValue;
|
||||
var ifaces = NetworkInterface.GetAllNetworkInterfaces();
|
||||
for (int i = 0; i < ifaces.Length; i++)
|
||||
{
|
||||
var ifc = ifaces[i];
|
||||
|
||||
if (ifc.OperationalStatus == OperationalStatus.Up && !ifc.IsReceiveOnly)
|
||||
{
|
||||
_logger?.LogTrace("Testing interface: {name}, {id}", ifc.Name, ifc.Id);
|
||||
|
||||
var props = ifc.GetIPProperties();
|
||||
var ipprops = props.GetIPv4Properties();
|
||||
|
||||
if (ipprops.Index < lowest || result == null)
|
||||
{
|
||||
lowest = ipprops.Index;
|
||||
}
|
||||
else if (result != null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!IgnoreInterface(ifc.Name))
|
||||
{
|
||||
foreach (var addressInfo in props.UnicastAddresses)
|
||||
{
|
||||
var address = addressInfo.Address;
|
||||
if (IsInet4Address(address)
|
||||
&& !IsLoopbackAddress(address)
|
||||
&& IsPreferredAddress(address))
|
||||
{
|
||||
_logger?.LogTrace("Found non-loopback interface: {name}", ifc.Name);
|
||||
result = address;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger?.LogError(ex, "Cannot get first non-loopback address");
|
||||
}
|
||||
|
||||
if (result != null)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
string localHost = GetHostAddress();
|
||||
if (!string.IsNullOrEmpty(localHost))
|
||||
{
|
||||
return IPAddress.Parse(localHost);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
internal bool IsInet4Address(IPAddress address)
|
||||
{
|
||||
return address.AddressFamily == AddressFamily.InterNetwork;
|
||||
}
|
||||
|
||||
internal bool IsLoopbackAddress(IPAddress address)
|
||||
{
|
||||
return IPAddress.IsLoopback(address);
|
||||
}
|
||||
|
||||
internal bool IsPreferredAddress(IPAddress address)
|
||||
{
|
||||
if (_options.UseOnlySiteLocalInterfaces)
|
||||
{
|
||||
bool siteLocalAddress = IsSiteLocalAddress(address);
|
||||
if (!siteLocalAddress)
|
||||
{
|
||||
_logger?.LogTrace("Ignoring address: {address} ", address.ToString());
|
||||
}
|
||||
|
||||
return siteLocalAddress;
|
||||
}
|
||||
|
||||
IEnumerable<string> preferredNetworks = _options.GetPreferredNetworks();
|
||||
if (preferredNetworks == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
foreach (string regex in preferredNetworks)
|
||||
{
|
||||
string hostAddress = address.ToString();
|
||||
var matcher = new Regex(regex);
|
||||
if (matcher.IsMatch(hostAddress) || hostAddress.StartsWith(regex))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
_logger?.LogTrace("Ignoring address: {address}", address.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
internal bool IgnoreInterface(string interfaceName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(interfaceName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (string regex in _options.GetIgnoredInterfaces())
|
||||
{
|
||||
var matcher = new Regex(regex);
|
||||
if (matcher.IsMatch(interfaceName))
|
||||
{
|
||||
_logger?.LogTrace("Ignoring interface: {name}", interfaceName);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
internal HostInfo ConvertAddress(IPAddress address)
|
||||
{
|
||||
HostInfo hostInfo = new HostInfo();
|
||||
string hostname;
|
||||
try
|
||||
{
|
||||
var hostEntry = Dns.GetHostEntry(address);
|
||||
hostname = hostEntry.HostName;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger?.LogInformation(e, "Cannot determine local hostname");
|
||||
hostname = "localhost";
|
||||
}
|
||||
|
||||
hostInfo.Hostname = hostname;
|
||||
hostInfo.IpAddress = address.ToString();
|
||||
return hostInfo;
|
||||
}
|
||||
|
||||
internal string ResolveHostAddress(string hostName)
|
||||
{
|
||||
string result = null;
|
||||
try
|
||||
{
|
||||
var results = Dns.GetHostAddresses(hostName);
|
||||
if (results != null && results.Length > 0)
|
||||
{
|
||||
foreach (var addr in results)
|
||||
{
|
||||
if (addr.AddressFamily.Equals(AddressFamily.InterNetwork))
|
||||
{
|
||||
result = addr.ToString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger?.LogWarning(e, "Unable to resolve host address");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
internal string ResolveHostName()
|
||||
{
|
||||
string result = null;
|
||||
try
|
||||
{
|
||||
result = Dns.GetHostName();
|
||||
if (!string.IsNullOrEmpty(result))
|
||||
{
|
||||
var response = Dns.GetHostEntry(result);
|
||||
if (response != null)
|
||||
{
|
||||
return response.HostName;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger?.LogWarning(e, "Unable to resolve hostname");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
internal string GetHostName()
|
||||
{
|
||||
return ResolveHostName();
|
||||
}
|
||||
|
||||
internal string GetHostAddress()
|
||||
{
|
||||
string hostName = GetHostName();
|
||||
if (!string.IsNullOrEmpty(hostName))
|
||||
{
|
||||
return ResolveHostAddress(hostName);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
internal bool IsSiteLocalAddress(IPAddress address)
|
||||
{
|
||||
string addr = address.ToString();
|
||||
return addr.StartsWith("10.") ||
|
||||
addr.StartsWith("172.16.") ||
|
||||
addr.StartsWith("192.168.");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using Xunit;
|
||||
|
||||
namespace Steeltoe.Common.Security.Test
|
||||
{
|
||||
public class PemConfigurationExtensionsTest
|
||||
{
|
||||
[Fact]
|
||||
public void AddPemFiles_ThrowsOnNulls()
|
||||
{
|
||||
Assert.Throws<ArgumentNullException>(() => PemConfigurationExtensions.AddPemFiles(null, null, null));
|
||||
Assert.Throws<ArgumentException>(() => PemConfigurationExtensions.AddPemFiles(new ConfigurationBuilder(), null, null));
|
||||
Assert.Throws<ArgumentException>(() => PemConfigurationExtensions.AddPemFiles(new ConfigurationBuilder(), "foobar", null));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AddPemFiles_ReadsFiles()
|
||||
{
|
||||
var config = new ConfigurationBuilder()
|
||||
.AddPemFiles("instance.crt", "instance.key")
|
||||
.Build();
|
||||
Assert.NotNull(config["certificate"]);
|
||||
Assert.NotNull(config["privateKey"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AddPemFiles_ReloadsOnChange()
|
||||
{
|
||||
var tempFile1 = CreateTempFile("cert");
|
||||
var tempFile2 = CreateTempFile("key");
|
||||
|
||||
var config = new ConfigurationBuilder()
|
||||
.AddPemFiles(tempFile1, tempFile2)
|
||||
.Build();
|
||||
|
||||
Assert.Equal("cert", config["certificate"]);
|
||||
Assert.Equal("key", config["privateKey"]);
|
||||
|
||||
File.WriteAllText(tempFile1, "cert2");
|
||||
Thread.Sleep(2000);
|
||||
Assert.Equal("cert2", config["certificate"]);
|
||||
Assert.Equal("key", config["privateKey"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AddPemFiles_NotifiesOnChange()
|
||||
{
|
||||
var tempFile1 = CreateTempFile("cert");
|
||||
var tempFile2 = CreateTempFile("key");
|
||||
|
||||
var config = new ConfigurationBuilder()
|
||||
.AddPemFiles(tempFile1, tempFile2)
|
||||
.Build();
|
||||
|
||||
bool changeCalled = false;
|
||||
var token = config.GetReloadToken();
|
||||
token.RegisterChangeCallback((o) => changeCalled = true, "state");
|
||||
Assert.Equal("cert", config["certificate"]);
|
||||
Assert.Equal("key", config["privateKey"]);
|
||||
|
||||
File.WriteAllText(tempFile1, "barfoo");
|
||||
Thread.Sleep(2000);
|
||||
Assert.Equal("barfoo", config["certificate"]);
|
||||
Assert.Equal("key", config["privateKey"]);
|
||||
Assert.True(changeCalled);
|
||||
|
||||
token = config.GetReloadToken();
|
||||
token.RegisterChangeCallback((o) => changeCalled = true, "state");
|
||||
|
||||
changeCalled = false;
|
||||
File.WriteAllText(tempFile2, "barbar");
|
||||
Thread.Sleep(2000);
|
||||
Assert.Equal("barfoo", config["certificate"]);
|
||||
Assert.Equal("barbar", config["privateKey"]);
|
||||
Assert.True(changeCalled);
|
||||
}
|
||||
|
||||
private static string CreateTempFile(string contents)
|
||||
{
|
||||
var tempFile = Path.GetTempFileName();
|
||||
File.WriteAllText(tempFile, contents);
|
||||
return tempFile;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Xunit;
|
||||
|
||||
namespace Steeltoe.Common.Security.Test
|
||||
{
|
||||
public class PemConfigureCertificateOptionsTest
|
||||
{
|
||||
[Fact]
|
||||
public void AddPemFiles_ReadsFiles_CreatesCertificate()
|
||||
{
|
||||
var config = new ConfigurationBuilder()
|
||||
.AddPemFiles("instance.crt", "instance.key")
|
||||
.Build();
|
||||
Assert.NotNull(config["certificate"]);
|
||||
Assert.NotNull(config["privateKey"]);
|
||||
var pemConfig = new PemConfigureCertificateOptions(config);
|
||||
CertificateOptions opts = new CertificateOptions();
|
||||
pemConfig.Configure(opts);
|
||||
Assert.NotNull(opts.Certificate);
|
||||
Assert.Equal(Options.DefaultName, opts.Name);
|
||||
Assert.True(opts.Certificate.HasPrivateKey);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<Import Project="..\..\versions.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netcoreapp2.0;netcoreapp2.1;net461</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="instance.crt">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="instance.key">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="xunit.runner.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<NoWarn>SA1101;SA1124;SA1201;SA1309;SA1310;SA1401;SA1600;SA1652;1591</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\Steeltoe.Common.Security\Steeltoe.Common.Security.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="$(ExtensionsVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options" Version="$(ExtensionsVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="$(ExtensionsVersion)" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(TestSdkVersion)" />
|
||||
<PackageReference Include="xunit" Version="$(XunitVersion)" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="$(XunitStudioVersion)" />
|
||||
<DotNetCliToolReference Include="dotnet-xunit" Version="$(XunitVersion)" />
|
||||
<PackageReference Include="StyleCop.Analyzers" Version="$(StyleCopVersion)">
|
||||
<PrivateAssets>All</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<AdditionalFiles Include="..\..\stylecop.json">
|
||||
<Link>stylecop.json</Link>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</AdditionalFiles>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIEBzCCAu+gAwIBAgIQSrLsvLyESbpjMDWmkPr+0TANBgkqhkiG9w0BAQsFADAy
|
||||
MTAwLgYDVQQDEydEaWVnbyBJbnN0YW5jZSBJZGVudGl0eSBJbnRlcm1lZGlhdGUg
|
||||
Q0EwHhcNMTkwMjI0MjAxMzAwWhcNMTkwMjI1MjAxMzAwWjCByDGBnjA4BgNVBAsT
|
||||
MW9yZ2FuaXphdGlvbjozOTBjYmI3Zi0wMWYyLTQ2MGUtOTViMi1jNjhmOGQ0YTk0
|
||||
YjgwMQYDVQQLEypzcGFjZTpjYzY4MmUyNi0yMTU1LTQ2NDktYjk0OC00ZjBkMDJm
|
||||
ODg3ZGEwLwYDVQQLEyhhcHA6M2ZlYzJmYjktNmIzYi00Yzc1LTkxYTktY2YwNDRi
|
||||
ZWIxOGU3MSUwIwYDVQQDExxjZmMyYmM0ZC1lODMxLTQ1ODgtNzY0My01NDQ0MIIB
|
||||
IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt2O/qEPoA0jQFrI23NRIzd3E
|
||||
FhsNwuTpZ4DoSVIZJQsjG0gjzoj0/YZHp6sbNRlWTHz1eXJ714+0rkYvpYjOp3jo
|
||||
EOJhsrx3Hs9eN0yDz+YqB+J3DSYt+t+nrae7wDBUAMFZXjqhrDhuFgANjsxF3Xtl
|
||||
1REgcRIdW9LGydAEAGlyMKAGBmQf9zofYCR+4Sw96KhQXBOTJiI+9p9pw3ndptfB
|
||||
hYCBdiifcHi6+e3nsOidqjrDP4PA6OfVMCxvzDkJLU2Bq1cjqHFomNB5Tc5AshyA
|
||||
lvDOi2+xVWBX7Z0+UujlWBYMeQl+FSz4N1cPYQ3SSNCDadkZHx/0f+qvRGX5eQID
|
||||
AQABo4GBMH8wDgYDVR0PAQH/BAQDAgOoMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggr
|
||||
BgEFBQcDATAfBgNVHSMEGDAWgBTBVXXc35U/Jlb+VYWm3AsyiodCETAtBgNVHREE
|
||||
JjAkghxjZmMyYmM0ZC1lODMxLTQ1ODgtNzY0My01NDQ0hwQK/0ilMA0GCSqGSIb3
|
||||
DQEBCwUAA4IBAQAYBwmgU99XJ/bFrkWYXKpb4PZClxbFk8eTGWuFQiREDtum13lU
|
||||
uxsWGWETLewJ7xEQzoEhWTbhOu8Kc0qILc+/dgoE+ENl59quwpFiWJNAu8gJYLga
|
||||
8JYaPL2RnCwx+7MBuAWkhNoX9fBWCrNo5NcJpyuaFJZPUCpmspDjQNf53ez/lnoV
|
||||
8hgCdTcBRFJgmbInSHIyy//k9Tv+6wisdZUsQf7y6O5HByKNNwSFbaEfKrSY38gb
|
||||
5lc9GBFsHxGgwJhy8y0y9ccMCHCMsEfKIJZPgJvyqjQqR3Y2AZiQCCexTi50f+lW
|
||||
ul0sbc6nZtCbml31604CjeVYA4jBCV3i6+T6
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDTTCCAjWgAwIBAgIUYnMnLAdY1eziifHiE6IDh958SnwwDQYJKoZIhvcNAQEL
|
||||
BQAwKjEoMCYGA1UEAxMfRGllZ28gSW5zdGFuY2UgSWRlbnRpdHkgUm9vdCBDQTAe
|
||||
Fw0xODExMTIyMDE3MzVaFw0yMDExMTEyMDE3MzVaMDIxMDAuBgNVBAMTJ0RpZWdv
|
||||
IEluc3RhbmNlIElkZW50aXR5IEludGVybWVkaWF0ZSBDQTCCASIwDQYJKoZIhvcN
|
||||
AQEBBQADggEPADCCAQoCggEBAKzttSjhIkimTDKEwCRWFeez/S/bFP23QIjHz+Y5
|
||||
dl7sdX8YXwdfWbqciS2EhJ6s1QCHwMToqLb6czRtzUz1TLdyMs9wuz9XzzgJHdNj
|
||||
yIb9B5aSbRudhTzGIAkY6HtjSA9lSD7gn66YBt/G5b+YHeZtFzc+Ao+Su5zJZ8AD
|
||||
7pWm0LP/q2Mahu+Pp3yx6dhkWV4MPDNJH6YBscQEZf08Hhew86b5adxGHmpR6ckU
|
||||
CpZUGHNOtE386eY6MgoN273cEj0UL7BH+YHGEeKGVrft7QYd5T/k9YC+Z7vmE9kw
|
||||
Ak5420Z7D3bg06y4qlguYHhqbxrlFW7HHjjrryc0Wfc7VRMCAwEAAaNjMGEwHQYD
|
||||
VR0OBBYEFMFVddzflT8mVv5VhabcCzKKh0IRMA4GA1UdDwEB/wQEAwICBDAfBgNV
|
||||
HSMEGDAWgBTFkeVheTtTImn4MXKxnOhKSBHcMzAPBgNVHRMBAf8EBTADAQH/MA0G
|
||||
CSqGSIb3DQEBCwUAA4IBAQBigPJqRSy13SP+vT9/dWGADoqTZSVE/JDvX4vbKuyg
|
||||
mOmV4hA3RbDa0vVBzDaMXLMjA4H/RFMCA3j99bec0RZXQT0sCnaYbFIU5msUEiP7
|
||||
11TY8advyq5GnZaGTXaEGGkmbWTsPKlLulnawtPdEtUQwZxYnh1nc6O0LqmbniwK
|
||||
zuHG478KmH8r779c6KCiwkA9K6OmMpT6wxJW0N88/tQ6EnJ2VSCGaJDhB+XbwJam
|
||||
s+pAhGCIOOuCD3fPYlz0QQ2UN/QwRAKDV1QTzGqYBesdZTRZtnDp1q/lZd7ETt8U
|
||||
iF9yZCtnfUN5lTLNs7ZCxy/3/I/tW90ssLVPY/+tfX/8
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,27 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEAt2O/qEPoA0jQFrI23NRIzd3EFhsNwuTpZ4DoSVIZJQsjG0gj
|
||||
zoj0/YZHp6sbNRlWTHz1eXJ714+0rkYvpYjOp3joEOJhsrx3Hs9eN0yDz+YqB+J3
|
||||
DSYt+t+nrae7wDBUAMFZXjqhrDhuFgANjsxF3Xtl1REgcRIdW9LGydAEAGlyMKAG
|
||||
BmQf9zofYCR+4Sw96KhQXBOTJiI+9p9pw3ndptfBhYCBdiifcHi6+e3nsOidqjrD
|
||||
P4PA6OfVMCxvzDkJLU2Bq1cjqHFomNB5Tc5AshyAlvDOi2+xVWBX7Z0+UujlWBYM
|
||||
eQl+FSz4N1cPYQ3SSNCDadkZHx/0f+qvRGX5eQIDAQABAoIBAQCK2Bh4+sCkC/KP
|
||||
3GmxE3/zbR1SZzUqA0m7NVuod2HWK/Jua1XAvuxNLeb+SIuWzhIKYukvA8BDWee/
|
||||
sh/MwiFDpkR81AiH3CyLxRBd6a46LtZPlePwrqFNORuoXD/HqE9RKxHQR6+zxh2C
|
||||
xpN9M6cJoq1cfVUEhmR36sLadIUzEVmGKVUhUv56kdrbwd3AEGrKkcWBl8N8ukCd
|
||||
1qV4IU7REwPjZBbfXSequ5goSKzzMG9MbKXLAj51btkCnMtLzfHfY3sSyfQIYO62
|
||||
7KJouNvdg3omNlygBsAuj4hM5nlg9uzuJQLrNEwnqOZXVGvkTXurZ+CrAN13Q5qf
|
||||
Xj4VyF0BAoGBAMkv+XKxH3Ck6KHsFENR3A2jb6UuvXHW77wzrN+pvXWPBZ0DhmxL
|
||||
PII/9clBnH4+EzINei4uhs0f0OL8+d0tqoOT0Qz6vOzhFKY/2/Cjk1ifff9uI1i3
|
||||
BpLjfPJyywy4HiVqjrTuDZjpp4Fj5v8jrI5Eg6Z5Xg4q3+qeAHR22ahpAoGBAOla
|
||||
c3r048V30LQf45Cg79uZaOtNNxCZwzcX0DZWqih0buwKfCEufhQ2ctpBbi9NeOt3
|
||||
9KEe2z5PT3B+uNzPBzkUGQ/6A/+aK9JVBEtNWqJI1nR6qMXB5t+d9iQrbIf56NHA
|
||||
1o3e1sAtXOvkVgh0o/ojwR//N+VMzQaDdlIvbiaRAoGBAJETukK9fRmCoYqaLeZ5
|
||||
skBXedvYv53Gy6uga+oBgfCzCO43q4iOHH0kWD4fxRS3+KmgVFnXDTf/2GbG2/tl
|
||||
wc8OGbLNYM1EZdqYtCZsHoXKxVYbevuvR9tGlkRTCR8L6hk7JNtNyppY64R/oQSd
|
||||
GgKhX3n9jRiUTFHoTBWv2rb5AoGAbUTNjmXdwjm4oJ/OD4tMxaewWX5uqndV0hZ0
|
||||
iP1L8GWVCzJdrav3nb9hSJIa5kuAs8IX6tpoD2VT7XlpVvwahb/DfJe2B5pJqtPk
|
||||
jt5J8nPo9+H35aJGWa+98nHjAEklnBKQZR5TsOmM+WiSYKM9pYPYiwMXSWgNGV+1
|
||||
qAZNrgECgYBoka0S/7jQt9TwQSRAagdmyBIo26JDQ6igqLB/lBrKgYAbqcTRmy2X
|
||||
bQZH1aCB/3B/NmIsqlzGOl/Uz3V6hW9Ae9X7BrXU4ug7SRH5BSff/eBY2j9YCR3e
|
||||
z9elUvEYUa59oaBtEJGXCOxjsypdjaR25LnW7/wVI3iBAiw6fAqlsw==
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"maxParallelThreads": 1,
|
||||
"parallelizeTestCollections": false
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
// Copyright 2017 the original author or authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
using System.Net;
|
||||
using Xunit;
|
||||
|
||||
namespace Steeltoe.Common.Net.Test
|
||||
{
|
||||
public class InetUtilsTest
|
||||
{
|
||||
[Fact]
|
||||
public void TestGetFirstNonLoopbackHostInfo()
|
||||
{
|
||||
InetUtils utils = new InetUtils(new InetOptions());
|
||||
Assert.NotNull(utils.FindFirstNonLoopbackHostInfo());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestGetFirstNonLoopbackAddress()
|
||||
{
|
||||
InetUtils utils = new InetUtils(new InetOptions());
|
||||
Assert.NotNull(utils.FindFirstNonLoopbackAddress());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestConvert()
|
||||
{
|
||||
InetUtils utils = new InetUtils(new InetOptions());
|
||||
Assert.NotNull(utils.ConvertAddress(Dns.GetHostEntry("localhost").AddressList[0]));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestHostInfo()
|
||||
{
|
||||
InetUtils utils = new InetUtils(new InetOptions());
|
||||
HostInfo info = utils.FindFirstNonLoopbackHostInfo();
|
||||
Assert.NotNull(info.IpAddress);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestIgnoreInterface()
|
||||
{
|
||||
InetOptions properties = new InetOptions()
|
||||
{
|
||||
IgnoredInterfaces = "docker0,veth.*"
|
||||
};
|
||||
|
||||
InetUtils inetUtils = new InetUtils(properties);
|
||||
|
||||
Assert.True(inetUtils.IgnoreInterface("docker0"));
|
||||
Assert.True(inetUtils.IgnoreInterface("vethAQI2QT"));
|
||||
Assert.False(inetUtils.IgnoreInterface("docker1"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestDefaultIgnoreInterface()
|
||||
{
|
||||
InetUtils inetUtils = new InetUtils(new InetOptions());
|
||||
Assert.False(inetUtils.IgnoreInterface("docker0"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestSiteLocalAddresses()
|
||||
{
|
||||
InetOptions properties = new InetOptions()
|
||||
{
|
||||
UseOnlySiteLocalInterfaces = true
|
||||
};
|
||||
|
||||
InetUtils utils = new InetUtils(properties);
|
||||
Assert.True(utils.IsPreferredAddress(IPAddress.Parse("192.168.0.1")));
|
||||
Assert.False(utils.IsPreferredAddress(IPAddress.Parse("5.5.8.1")));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestPreferredNetworksRegex()
|
||||
{
|
||||
InetOptions properties = new InetOptions()
|
||||
{
|
||||
PreferredNetworks = "192.168.*,10.0.*"
|
||||
};
|
||||
|
||||
InetUtils utils = new InetUtils(properties);
|
||||
Assert.True(utils.IsPreferredAddress(IPAddress.Parse("192.168.0.1")));
|
||||
Assert.False(utils.IsPreferredAddress(IPAddress.Parse("5.5.8.1")));
|
||||
Assert.True(utils.IsPreferredAddress(IPAddress.Parse("10.0.10.1")));
|
||||
Assert.False(utils.IsPreferredAddress(IPAddress.Parse("10.255.10.1")));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestPreferredNetworksSimple()
|
||||
{
|
||||
InetOptions properties = new InetOptions()
|
||||
{
|
||||
PreferredNetworks = "192,10.0"
|
||||
};
|
||||
|
||||
InetUtils utils = new InetUtils(properties);
|
||||
Assert.True(utils.IsPreferredAddress(IPAddress.Parse("192.168.0.1")));
|
||||
Assert.False(utils.IsPreferredAddress(IPAddress.Parse("5.5.8.1")));
|
||||
Assert.False(utils.IsPreferredAddress(IPAddress.Parse("10.255.10.1")));
|
||||
Assert.True(utils.IsPreferredAddress(IPAddress.Parse("10.0.10.1")));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestPreferredNetworksListIsEmpty()
|
||||
{
|
||||
InetOptions properties = new InetOptions();
|
||||
|
||||
InetUtils utils = new InetUtils(properties);
|
||||
Assert.True(utils.IsPreferredAddress(IPAddress.Parse("192.168.0.1")));
|
||||
Assert.True(utils.IsPreferredAddress(IPAddress.Parse("5.5.8.1")));
|
||||
Assert.True(utils.IsPreferredAddress(IPAddress.Parse("10.255.10.1")));
|
||||
Assert.True(utils.IsPreferredAddress(IPAddress.Parse("10.0.10.1")));
|
||||
}
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче