Fix .Net 4.6 Https client and server (#359)

- best possible fix for #189 to reenable https servers 
- `UA Sample Client` and `UA Sample Server` expose https server. libuv.dll is by default for x64. Change 
```
<PropertyGroup>
   <RuntimeIdentifier>win7-x64</RuntimeIdentifier>
   <BaseNuGetRuntimeIdentifier>win7-x64</BaseNuGetRuntimeIdentifier>
</PropertyGroup>
```
to win7-x86 if required.
- fix exception in https client when setting the Timeout
- fix travis build script for linux. kestrel server on ubuntu doesn't respond on ipv6Any ipaddress.
- fix a timing problem in the travis script.
This commit is contained in:
Martin Regen
2018-02-20 11:27:00 +01:00
committed by GitHub
parent 4d05093462
commit 75d8b2ca3c
10 changed files with 163 additions and 115 deletions
@@ -137,6 +137,7 @@
http://localhost:61211/UA/SampleClient/Basic256 -->
<BaseAddresses>
<ua:String>opc.tcp://localhost:61210/UA/SampleClient</ua:String>
<ua:String>https://localhost:61212/UA/SampleClient</ua:String>
</BaseAddresses>
<!--
@@ -167,7 +168,7 @@
<SecurityPolicies>
<ServerSecurityPolicy>
<SecurityMode>SignAndEncrypt_3</SecurityMode>
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic128Rsa15</SecurityPolicyUri>
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256</SecurityPolicyUri>
</ServerSecurityPolicy>
<ServerSecurityPolicy>
<SecurityMode>Sign_2</SecurityMode>
@@ -182,17 +183,17 @@
<SecurityMode>Sign_2</SecurityMode>
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic128Rsa15</SecurityPolicyUri>
</ServerSecurityPolicy>
<ServerSecurityPolicy>
<SecurityMode>SignAndEncrypt_3</SecurityMode>
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic256</SecurityPolicyUri>
</ServerSecurityPolicy>
<ServerSecurityPolicy>
<SecurityMode>Sign_2</SecurityMode>
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256</SecurityPolicyUri>
</ServerSecurityPolicy>
<ServerSecurityPolicy>
<SecurityMode>SignAndEncrypt_3</SecurityMode>
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256</SecurityPolicyUri>
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic256</SecurityPolicyUri>
</ServerSecurityPolicy>
<ServerSecurityPolicy>
<SecurityMode>SignAndEncrypt_3</SecurityMode>
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic128Rsa15</SecurityPolicyUri>
</ServerSecurityPolicy>
</SecurityPolicies>
@@ -34,6 +34,36 @@
<ua:UpdateBeforeConnect>true</ua:UpdateBeforeConnect>
<ua:SelectedUserTokenPolicy>0</ua:SelectedUserTokenPolicy>
</ua:ConfiguredEndpoint>
<!--
Self, acting as a server endpoint:
https://localhost:61212/UA/SampleClient // -->
<ua:ConfiguredEndpoint>
<ua:Endpoint>
<EndpointUrl>https://localhost:61212/UA/SampleClient</EndpointUrl>
<SecurityMode>SignAndEncrypt_3</SecurityMode>
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256</SecurityPolicyUri>
<UserIdentityTokens>
<UserTokenPolicy>
<TokenType>Anonymous_0</TokenType>
</UserTokenPolicy>
<UserTokenPolicy>
<TokenType>UserName_1</TokenType>
</UserTokenPolicy>
<UserTokenPolicy>
<TokenType>Certificate_2</TokenType>
</UserTokenPolicy>
<UserTokenPolicy>
<PolicyId xsi:nil="true" />
<TokenType>IssuedToken_3</TokenType>
<IssuedTokenType>urn:oasis:names:tc:SAML:1.0:assertion:Assertion</IssuedTokenType>
</UserTokenPolicy>
</UserIdentityTokens>
<TransportProfileUri>http://opcfoundation.org/UA/profiles/transport/wsxmlorbinary</TransportProfileUri>
</ua:Endpoint>
<ua:UpdateBeforeConnect>true</ua:UpdateBeforeConnect>
<ua:SelectedUserTokenPolicy>0</ua:SelectedUserTokenPolicy>
</ua:ConfiguredEndpoint>
<!--
Sample server, opc.tcp endpoint:
@@ -64,6 +94,36 @@
<ua:UpdateBeforeConnect>true</ua:UpdateBeforeConnect>
<ua:SelectedUserTokenPolicy>0</ua:SelectedUserTokenPolicy>
</ua:ConfiguredEndpoint>
<!--
Sample server, opc.tcp endpoint:
https://localhost:51212/UA/SampleServer // -->
<ua:ConfiguredEndpoint>
<ua:Endpoint>
<EndpointUrl>https://localhost:51212/UA/SampleServer</EndpointUrl>
<SecurityMode>SignAndEncrypt_3</SecurityMode>
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256</SecurityPolicyUri>
<UserIdentityTokens>
<UserTokenPolicy>
<TokenType>Anonymous_0</TokenType>
</UserTokenPolicy>
<UserTokenPolicy>
<TokenType>UserName_1</TokenType>
</UserTokenPolicy>
<UserTokenPolicy>
<TokenType>Certificate_2</TokenType>
</UserTokenPolicy>
<UserTokenPolicy>
<PolicyId xsi:nil="true" />
<TokenType>IssuedToken_3</TokenType>
<IssuedTokenType>urn:oasis:names:tc:SAML:1.0:assertion:Assertion</IssuedTokenType>
</UserTokenPolicy>
</UserIdentityTokens>
<TransportProfileUri>http://opcfoundation.org/UA/profiles/transport/wsxmlorbinary</TransportProfileUri>
</ua:Endpoint>
<ua:UpdateBeforeConnect>true</ua:UpdateBeforeConnect>
<ua:SelectedUserTokenPolicy>0</ua:SelectedUserTokenPolicy>
</ua:ConfiguredEndpoint>
<!--
Reference server, opc.tcp endpoint:
@@ -19,27 +19,12 @@
<OldToolsVersion>3.5</OldToolsVersion>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<IsWebBootstrapper>true</IsWebBootstrapper>
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
<SignAssembly>false</SignAssembly>
<AssemblyOriginatorKeyFile>
</AssemblyOriginatorKeyFile>
<ApplicationManifest>app.manifest</ApplicationManifest>
<TargetFrameworkProfile />
<PublishUrl>http://localhost/Opc.Ua.SampleClient/</PublishUrl>
<Install>true</Install>
<InstallFrom>Web</InstallFrom>
<UpdateEnabled>true</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -109,6 +94,7 @@
</EmbeddedResource>
<Content Include="Opc.Ua.SampleClient.Config.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<SubType>Designer</SubType>
</Content>
<Content Include="Opc.Ua.SampleClient.Endpoints.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
@@ -161,33 +147,6 @@
<Name>Opc.Ua.Sample</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework Client Profile</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
<Visible>False</Visible>
<ProductName>.NET Framework 2.0 %28x86%29</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.0">
<Visible>False</Visible>
<ProductName>.NET Framework 3.0 %28x86%29</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>false</Install>
</BootstrapperPackage>
</ItemGroup>
<ItemGroup>
<Content Include="app.manifest" />
</ItemGroup>
@@ -196,6 +155,10 @@
<Version>4.3.3</Version>
</PackageReference>
</ItemGroup>
<PropertyGroup>
<RuntimeIdentifier>win7-x64</RuntimeIdentifier>
<BaseNuGetRuntimeIdentifier>win7-x64</BaseNuGetRuntimeIdentifier>
</PropertyGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
@@ -55,6 +55,7 @@
<ServerConfiguration>
<BaseAddresses>
<ua:String>opc.tcp://localhost:51210/UA/SampleServer</ua:String>
<ua:String>https://localhost:51212/UA/SampleServer</ua:String>
</BaseAddresses>
<!--
@@ -77,33 +78,33 @@
<SecurityPolicies>
<ServerSecurityPolicy>
<SecurityMode>SignAndEncrypt_3</SecurityMode>
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256</SecurityPolicyUri>
</ServerSecurityPolicy>
<ServerSecurityPolicy>
<SecurityMode>Sign_2</SecurityMode>
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic128Rsa15</SecurityPolicyUri>
</ServerSecurityPolicy>
<ServerSecurityPolicy>
<SecurityMode>Sign_2</SecurityMode>
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic256</SecurityPolicyUri>
</ServerSecurityPolicy>
<ServerSecurityPolicy>
<SecurityMode>Sign_2</SecurityMode>
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256</SecurityPolicyUri>
</ServerSecurityPolicy>
<!--Removing no security option from the configuration as this is a security risk
<ServerSecurityPolicy>
<SecurityMode>None_1</SecurityMode>
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#None</SecurityPolicyUri>
</ServerSecurityPolicy>-->
<ServerSecurityPolicy>
<SecurityMode>Sign_2</SecurityMode>
<SecurityMode>SignAndEncrypt_3</SecurityMode>
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic128Rsa15</SecurityPolicyUri>
</ServerSecurityPolicy>
<ServerSecurityPolicy>
<SecurityMode>SignAndEncrypt_3</SecurityMode>
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic256</SecurityPolicyUri>
</ServerSecurityPolicy>
<ServerSecurityPolicy>
<SecurityMode>Sign_2</SecurityMode>
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256</SecurityPolicyUri>
</ServerSecurityPolicy>
<ServerSecurityPolicy>
<SecurityMode>SignAndEncrypt_3</SecurityMode>
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256</SecurityPolicyUri>
</ServerSecurityPolicy>
</SecurityPolicies>
<MinRequestThreadCount>5</MinRequestThreadCount>
@@ -153,6 +153,10 @@
<ItemGroup>
<None Include="app.manifest" />
</ItemGroup>
<PropertyGroup>
<RuntimeIdentifier>win7-x64</RuntimeIdentifier>
<BaseNuGetRuntimeIdentifier>win7-x64</BaseNuGetRuntimeIdentifier>
</PropertyGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
@@ -236,7 +236,7 @@ namespace Opc.Ua
InternalValidate(chain).Wait();
// add to list of validated certificates.
m_validatedCertificates[certificate.Thumbprint] = certificate;
m_validatedCertificates[certificate.Thumbprint] = new X509Certificate2(certificate.RawData);
}
}
catch (AggregateException ae)
@@ -187,12 +187,7 @@ namespace Opc.Ua.Bindings
httpsOptions.ServerCertificate = m_serverCert;
httpsOptions.SslProtocols = SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12;
m_host.UseKestrel(options =>
{
options.Listen(IPAddress.IPv6Any, m_uri.Port, listenOptions =>
{
listenOptions.NoDelay = true;
listenOptions.UseHttps(httpsOptions);
});
{
options.Listen(IPAddress.Any, m_uri.Port, listenOptions =>
{
listenOptions.NoDelay = true;
@@ -25,7 +25,7 @@ namespace Opc.Ua.Bindings
public class HttpsTransportChannel : ITransportChannel
{
public void Dispose()
{
{
}
public TransportChannelFeatures SupportedFeatures
@@ -50,7 +50,7 @@ namespace Opc.Ua.Bindings
public int OperationTimeout
{
get { return m_operationTimeout; }
get { return m_operationTimeout; }
set { m_operationTimeout = value; }
}
@@ -60,7 +60,7 @@ namespace Opc.Ua.Bindings
{
SaveSettings(url, settings);
}
public void Open()
{
try
@@ -79,7 +79,17 @@ namespace Opc.Ua.Bindings
handler.ServerCertificateCustomValidationCallback =
(httpRequestMessage, cert, chain, policyErrors) =>
{
return true;
try
{
m_quotas.CertificateValidator?.Validate(cert);
return true;
}
catch (Exception ex)
{
Utils.Trace("HTTPS: Failed to validate server cert: " + cert.Subject);
Utils.Trace("HTTPS: Exception:" + ex.Message);
}
return false;
};
}
catch (PlatformNotSupportedException)
@@ -135,23 +145,22 @@ namespace Opc.Ua.Bindings
content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
AsyncResult result = new AsyncResult(callback, callbackData, m_operationTimeout, request, null);
m_client.Timeout = TimeSpan.FromMilliseconds(m_operationTimeout);
Task.Run( async () =>
{
try
{
response = await m_client.PostAsync(m_url, content);
response.EnsureSuccessStatusCode();
}
catch (Exception ex)
{
Utils.Trace("Exception sending HTTPS request: " + ex.Message);
result.Exception = ex;
response = null;
}
result.Response = response;
result.OperationCompleted();
});
Task.Run(async () =>
{
try
{
response = await m_client.PostAsync(m_url, content);
response.EnsureSuccessStatusCode();
}
catch (Exception ex)
{
Utils.Trace("Exception sending HTTPS request: " + ex.Message);
result.Exception = ex;
response = null;
}
result.Response = response;
result.OperationCompleted();
});
return result;
}
@@ -214,7 +223,7 @@ namespace Opc.Ua.Bindings
{
throw new NotImplementedException();
}
public IAsyncResult BeginClose(AsyncCallback callback, object callbackData)
{
throw new NotImplementedException();
@@ -230,10 +239,10 @@ namespace Opc.Ua.Bindings
IAsyncResult result = BeginSendRequest(request, null, null);
return EndSendRequest(result);
}
private void SaveSettings(Uri url, TransportChannelSettings settings)
{
m_url = new Uri(Utils.ReplaceLocalhost(url.ToString()));
m_url = new Uri(url.ToString());
m_settings = settings;
m_operationTimeout = settings.Configuration.OperationTimeout;
+11 -11
View File
@@ -828,25 +828,25 @@ namespace Opc.Ua
if (uri.Scheme == Utils.UriSchemeHttps)
{
// can only support one policy with HTTPS so pick the best one.
// Can only support one policy with HTTPS so pick the
// first secure policy with sign and encrypt in the list
ServerSecurityPolicy bestPolicy = null;
byte bestLevel = 0;
foreach (ServerSecurityPolicy policy in securityPolicies)
{
if (bestPolicy == null)
if (policy.SecurityMode != MessageSecurityMode.SignAndEncrypt)
{
bestPolicy = policy;
continue;
}
byte securityLevel = ServerSecurityPolicy.CalculateSecurityLevel(policy.SecurityMode, policy.SecurityPolicyUri);
if (bestLevel < securityLevel)
{
bestPolicy = policy;
bestLevel = securityLevel;
}
bestPolicy = policy;
break;
}
if (bestPolicy == null)
{
throw new ServiceResultException("HTTPS transport requires policy with sign and encrypt.");
}
EndpointDescription description = new EndpointDescription();
description.EndpointUrl = uri.ToString();
+31 -16
View File
@@ -9,18 +9,29 @@ cd SampleApplications/Samples/NetCoreConsoleServer
echo build server
rm -r obj
dotnet build NetCoreConsoleServer.csproj
echo start server
dotnet run --no-restore --no-build --project NetCoreConsoleServer.csproj -t 60 -a &
serverpid="$!"
cd $workdir
cd SampleApplications/Samples/NetCoreConsoleClient
cd ../NetCoreConsoleClient
echo build client
rm -r obj
dotnet build NetCoreConsoleClient.csproj
echo start client
dotnet run --no-restore --no-build --project NetCoreConsoleClient.csproj -t 10 -a &
cd $workdir
cd SampleApplications/Samples/NetCoreConsoleServer
echo start server
touch ./server.log
dotnet run --no-restore --no-build --project NetCoreConsoleServer.csproj -t 60 -a >./server.log &
serverpid="$!"
echo wait for server started
grep -m 1 "start" <(tail -f ./server.log --pid=$serverpid)
tail -f ./server.log --pid=$serverpid &
cd $workdir
cd SampleApplications/Samples/NetCoreConsoleClient
echo start client for tcp connection
dotnet run --no-restore --no-build --project NetCoreConsoleClient.csproj -t 20 -a &
clientpid="$!"
echo start client for https connection
dotnet run --no-restore --no-build --project NetCoreConsoleClient.csproj -t 20 -a https://localhost:51212 &
httpsclientpid="$!"
cd $workdir
echo wait for opc.tcp client
@@ -33,21 +44,25 @@ else
fi
cd SampleApplications/Samples/NetCoreConsoleClient
echo start client for https connection
dotnet run --no-restore --no-build --project NetCoreConsoleClient.csproj -t 10 -a https://localhost:51212 &
clientpid="$!"
cd $workdir
echo wait for opc.tcp client
wait $clientpid
echo wait for https client
wait $httpsclientpid
if [ $? -eq 0 ]; then
echo "SUCCESS - Client test passed"
else
testresulthttps=$?
echo "WARN - Client test failed with a status of $testresulthttps"
echo "WARN - Client may require to use trusted TLS server cert to pass this test"
echo "FAILED - Client test failed with a status of $testresulthttps"
echo "FAILED - Client may require to use trusted TLS server cert to pass this test"
if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
testresulthttps=0
echo "IGNORED - test requires trusted TLS cert on OSX"
fi
fi
echo send Ctrl-C to server
kill -s SIGINT $serverpid
echo wait for server
wait $serverpid
serverresult=$?
@@ -60,7 +75,7 @@ else
fi
echo "Test results: Client:$testresult Server:$serverresult ClientHttps:$testresulthttps"
exit $((testresult + serverresult))
exit $((testresult + serverresult + testresulthttps))