diff options
Diffstat (limited to 'src/csharp')
-rw-r--r-- | src/csharp/Grpc.Core/Grpc.Core.csproj | 9 | ||||
-rw-r--r-- | src/csharp/Grpc.Core/Grpc.Core.nuspec | 1 | ||||
-rw-r--r-- | src/csharp/Grpc.Core/Internal/DefaultSslRootsOverride.cs | 72 | ||||
-rw-r--r-- | src/csharp/Grpc.Core/Internal/NativeExtension.cs | 2 | ||||
-rw-r--r-- | src/csharp/Grpc.Core/Internal/NativeMethods.cs | 7 | ||||
-rw-r--r-- | src/csharp/Grpc.Core/Internal/PlatformApis.cs | 7 | ||||
-rw-r--r-- | src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs | 24 | ||||
-rw-r--r-- | src/csharp/build_packages.bat | 4 | ||||
-rw-r--r-- | src/csharp/ext/grpc_csharp_ext.c | 27 |
9 files changed, 151 insertions, 2 deletions
diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj index 307c0e8783..9587503e4b 100644 --- a/src/csharp/Grpc.Core/Grpc.Core.csproj +++ b/src/csharp/Grpc.Core/Grpc.Core.csproj @@ -128,6 +128,7 @@ <Compile Include="Profiling\ProfilerScope.cs" /> <Compile Include="Profiling\IProfiler.cs" /> <Compile Include="Profiling\Profilers.cs" /> + <Compile Include="Internal\DefaultSslRootsOverride.cs" /> </ItemGroup> <ItemGroup> <None Include="Grpc.Core.nuspec" /> @@ -135,4 +136,12 @@ </ItemGroup> <Import Project="NativeDeps.targets" /> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> + <ItemGroup> + <Folder Include="Resources\" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="..\..\..\etc\roots.pem"> + <Link>Resources\roots.pem</Link> + </EmbeddedResource> + </ItemGroup> </Project>
\ No newline at end of file diff --git a/src/csharp/Grpc.Core/Grpc.Core.nuspec b/src/csharp/Grpc.Core/Grpc.Core.nuspec index 9a4c1a3c85..49bccb050e 100644 --- a/src/csharp/Grpc.Core/Grpc.Core.nuspec +++ b/src/csharp/Grpc.Core/Grpc.Core.nuspec @@ -20,7 +20,6 @@ </dependencies> </metadata> <files> - <file src="..\..\..\etc\roots.pem" target="tools" /> <file src="bin/ReleaseSigned/Grpc.Core.dll" target="lib/net45" /> <file src="bin/ReleaseSigned/Grpc.Core.pdb" target="lib/net45" /> <file src="bin/ReleaseSigned/Grpc.Core.xml" target="lib/net45" /> diff --git a/src/csharp/Grpc.Core/Internal/DefaultSslRootsOverride.cs b/src/csharp/Grpc.Core/Internal/DefaultSslRootsOverride.cs new file mode 100644 index 0000000000..eeaa7add81 --- /dev/null +++ b/src/csharp/Grpc.Core/Internal/DefaultSslRootsOverride.cs @@ -0,0 +1,72 @@ +#region Copyright notice and license + +// Copyright 2015-2016, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#endregion + +using System; +using System.Collections.Concurrent; +using System.Diagnostics; +using System.IO; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Threading; + +namespace Grpc.Core.Internal +{ + /// <summary> + /// Overrides the content of default SSL roots. + /// </summary> + internal static class DefaultSslRootsOverride + { + const string RootsPemResourceName = "Grpc.Core.Resources.roots.pem"; + static object staticLock = new object(); + + /// <summary> + /// Overrides C core's default roots with roots.pem loaded as embedded resource. + /// </summary> + public static void Override(NativeMethods native) + { + lock (staticLock) + { + var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(RootsPemResourceName); + if (stream == null) + { + throw new IOException(string.Format("Error loading the embedded resource \"{0}\"", RootsPemResourceName)); + } + using (var streamReader = new StreamReader(stream)) + { + var pemRootCerts = streamReader.ReadToEnd(); + native.grpcsharp_override_default_ssl_roots(pemRootCerts); + } + } + } + } +} diff --git a/src/csharp/Grpc.Core/Internal/NativeExtension.cs b/src/csharp/Grpc.Core/Internal/NativeExtension.cs index 137533b3ef..e14d33ea50 100644 --- a/src/csharp/Grpc.Core/Internal/NativeExtension.cs +++ b/src/csharp/Grpc.Core/Internal/NativeExtension.cs @@ -60,6 +60,8 @@ namespace Grpc.Core.Internal // to make sure we don't lose any logs. NativeLogRedirector.Redirect(this.nativeMethods); + DefaultSslRootsOverride.Override(this.nativeMethods); + Logger.Debug("gRPC native library loaded successfully."); } diff --git a/src/csharp/Grpc.Core/Internal/NativeMethods.cs b/src/csharp/Grpc.Core/Internal/NativeMethods.cs index af37d61c73..19a573581e 100644 --- a/src/csharp/Grpc.Core/Internal/NativeMethods.cs +++ b/src/csharp/Grpc.Core/Internal/NativeMethods.cs @@ -97,6 +97,7 @@ namespace Grpc.Core.Internal public readonly Delegates.grpcsharp_channel_args_set_integer_delegate grpcsharp_channel_args_set_integer; public readonly Delegates.grpcsharp_channel_args_destroy_delegate grpcsharp_channel_args_destroy; + public readonly Delegates.grpcsharp_override_default_ssl_roots grpcsharp_override_default_ssl_roots; public readonly Delegates.grpcsharp_ssl_credentials_create_delegate grpcsharp_ssl_credentials_create; public readonly Delegates.grpcsharp_composite_channel_credentials_create_delegate grpcsharp_composite_channel_credentials_create; public readonly Delegates.grpcsharp_channel_credentials_release_delegate grpcsharp_channel_credentials_release; @@ -203,6 +204,7 @@ namespace Grpc.Core.Internal this.grpcsharp_channel_args_set_integer = GetMethodDelegate<Delegates.grpcsharp_channel_args_set_integer_delegate>(library); this.grpcsharp_channel_args_destroy = GetMethodDelegate<Delegates.grpcsharp_channel_args_destroy_delegate>(library); + this.grpcsharp_override_default_ssl_roots = GetMethodDelegate<Delegates.grpcsharp_override_default_ssl_roots>(library); this.grpcsharp_ssl_credentials_create = GetMethodDelegate<Delegates.grpcsharp_ssl_credentials_create_delegate>(library); this.grpcsharp_composite_channel_credentials_create = GetMethodDelegate<Delegates.grpcsharp_composite_channel_credentials_create_delegate>(library); this.grpcsharp_channel_credentials_release = GetMethodDelegate<Delegates.grpcsharp_channel_credentials_release_delegate>(library); @@ -306,6 +308,7 @@ namespace Grpc.Core.Internal this.grpcsharp_channel_args_set_integer = PInvokeMethods.grpcsharp_channel_args_set_integer; this.grpcsharp_channel_args_destroy = PInvokeMethods.grpcsharp_channel_args_destroy; + this.grpcsharp_override_default_ssl_roots = PInvokeMethods.grpcsharp_override_default_ssl_roots; this.grpcsharp_ssl_credentials_create = PInvokeMethods.grpcsharp_ssl_credentials_create; this.grpcsharp_composite_channel_credentials_create = PInvokeMethods.grpcsharp_composite_channel_credentials_create; this.grpcsharp_channel_credentials_release = PInvokeMethods.grpcsharp_channel_credentials_release; @@ -449,6 +452,7 @@ namespace Grpc.Core.Internal public delegate void grpcsharp_channel_args_set_integer_delegate(ChannelArgsSafeHandle args, UIntPtr index, string key, int value); public delegate void grpcsharp_channel_args_destroy_delegate(IntPtr args); + public delegate void grpcsharp_override_default_ssl_roots(string pemRootCerts); public delegate ChannelCredentialsSafeHandle grpcsharp_ssl_credentials_create_delegate(string pemRootCerts, string keyCertPairCertChain, string keyCertPairPrivateKey); public delegate ChannelCredentialsSafeHandle grpcsharp_composite_channel_credentials_create_delegate(ChannelCredentialsSafeHandle channelCreds, CallCredentialsSafeHandle callCreds); public delegate void grpcsharp_channel_credentials_release_delegate(IntPtr credentials); @@ -658,6 +662,9 @@ namespace Grpc.Core.Internal // ChannelCredentialsSafeHandle [DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)] + public static extern void grpcsharp_override_default_ssl_roots(string pemRootCerts); + + [DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)] public static extern ChannelCredentialsSafeHandle grpcsharp_ssl_credentials_create(string pemRootCerts, string keyCertPairCertChain, string keyCertPairPrivateKey); [DllImport("grpc_csharp_ext.dll")] diff --git a/src/csharp/Grpc.Core/Internal/PlatformApis.cs b/src/csharp/Grpc.Core/Internal/PlatformApis.cs index d71e7eccdd..f0c5b0f63f 100644 --- a/src/csharp/Grpc.Core/Internal/PlatformApis.cs +++ b/src/csharp/Grpc.Core/Internal/PlatformApis.cs @@ -49,6 +49,7 @@ namespace Grpc.Core.Internal static readonly bool isLinux; static readonly bool isMacOSX; static readonly bool isWindows; + static readonly bool isMono; static PlatformApis() { @@ -58,6 +59,7 @@ namespace Grpc.Core.Internal isMacOSX = (platform == PlatformID.Unix && GetUname() == "Darwin"); isLinux = (platform == PlatformID.Unix && !isMacOSX); isWindows = (platform == PlatformID.Win32NT || platform == PlatformID.Win32S || platform == PlatformID.Win32Windows); + isMono = Type.GetType("Mono.Runtime") != null; } public static bool IsLinux @@ -75,6 +77,11 @@ namespace Grpc.Core.Internal get { return isWindows; } } + public static bool IsMono + { + get { return isMono; } + } + public static bool Is64Bit { get { return IntPtr.Size == 8; } diff --git a/src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs b/src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs index e614cab6ab..95a8797e3e 100644 --- a/src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs +++ b/src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs @@ -91,6 +91,10 @@ namespace Grpc.Core.Internal { if (PlatformApis.IsLinux) { + if (PlatformApis.IsMono) + { + return Mono.dlsym(this.handle, symbolName); + } return Linux.dlsym(this.handle, symbolName); } if (PlatformApis.IsMacOSX) @@ -122,6 +126,10 @@ namespace Grpc.Core.Internal } if (PlatformApis.IsLinux) { + if (PlatformApis.IsMono) + { + return Mono.dlopen(libraryPath, RTLD_GLOBAL + RTLD_LAZY); + } return Linux.dlopen(libraryPath, RTLD_GLOBAL + RTLD_LAZY); } if (PlatformApis.IsMacOSX) @@ -154,5 +162,21 @@ namespace Grpc.Core.Internal [DllImport("libSystem.dylib")] internal static extern IntPtr dlsym(IntPtr handle, string symbol); } + + /// <summary> + /// On Linux systems, using using dlopen and dlsym results in + /// DllNotFoundException("libdl.so not found") if libc6-dev + /// is not installed. As a workaround, we load symbols for + /// dlopen and dlsym from the current process as on Linux + /// Mono sure is linked against these symbols. + /// </summary> + private static class Mono + { + [DllImport("__Internal")] + internal static extern IntPtr dlopen(string filename, int flags); + + [DllImport("__Internal")] + internal static extern IntPtr dlsym(IntPtr handle, string symbol); + } } } diff --git a/src/csharp/build_packages.bat b/src/csharp/build_packages.bat index 7a34bf3fd6..e423545ef8 100644 --- a/src/csharp/build_packages.bat +++ b/src/csharp/build_packages.bat @@ -49,6 +49,10 @@ endlocal @rem copy resulting nuget packages to artifacts directory xcopy /Y /I *.nupkg ..\..\artifacts\ +@rem create a zipfile with the artifacts as well +powershell -Command "Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::CreateFromDirectory('..\..\artifacts', 'csharp_nugets.zip');" +xcopy /Y /I csharp_nugets.zip ..\..\artifacts\ + goto :EOF :error diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c index 26f1537398..1df74a0993 100644 --- a/src/csharp/ext/grpc_csharp_ext.c +++ b/src/csharp/ext/grpc_csharp_ext.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -835,6 +835,30 @@ grpcsharp_server_request_call(grpc_server *server, grpc_completion_queue *cq, /* Security */ +static char *default_pem_root_certs = NULL; + +static grpc_ssl_roots_override_result override_ssl_roots_handler( + char **pem_root_certs) { + if (!default_pem_root_certs) { + *pem_root_certs = NULL; + return GRPC_SSL_ROOTS_OVERRIDE_FAIL_PERMANENTLY; + } + *pem_root_certs = gpr_strdup(default_pem_root_certs); + return GRPC_SSL_ROOTS_OVERRIDE_OK; +} + +GPR_EXPORT void GPR_CALLTYPE grpcsharp_override_default_ssl_roots( + const char *pem_root_certs) { + /* + * This currently wastes ~300kB of memory by keeping a copy of roots + * in a static variable, but for desktop/server use, the overhead + * is negligible. In the future, we might want to change the behavior + * for mobile (e.g. Xamarin). + */ + default_pem_root_certs = gpr_strdup(pem_root_certs); + grpc_set_ssl_roots_override_callback(override_ssl_roots_handler); +} + GPR_EXPORT grpc_channel_credentials *GPR_CALLTYPE grpcsharp_ssl_credentials_create(const char *pem_root_certs, const char *key_cert_pair_cert_chain, @@ -917,6 +941,7 @@ GPR_EXPORT grpc_call_credentials *GPR_CALLTYPE grpcsharp_composite_call_credenti return grpc_composite_call_credentials_create(creds1, creds2, NULL); } + /* Metadata credentials plugin */ GPR_EXPORT void GPR_CALLTYPE grpcsharp_metadata_credentials_notify_from_plugin( |