From 2f30434fe3526b306dcdb0da78dadf84efa315fc Mon Sep 17 00:00:00 2001 From: John Soo Date: Wed, 8 Nov 2023 23:16:04 -0700 Subject: [PATCH] Grpc 1.45+ support (#157) * nixpkgs.nix: Bump to 2022-04-22. * release.nix: Unmark data-diverse as broken. * *.nix: Adjust to nixpkgs update. * cbits: Adjust to removal of insecure build. See https://github.com/grpc/grpc/pull/25586 * Do not make secure connections mandatory Instead of making secure connections mandatory, use insecure credentials to keep existing API unchanged. * release.nix: Make sure .sh scripts are executable before wrapping. It seems as though the `./Setup sdist` now unsets the executable bit. * README: Update supported gRPC version. --------- Co-authored-by: Raghu Kaippully --- README.md | 2 +- core/src/Network/GRPC/LowLevel/Client.hs | 8 +++++--- core/src/Network/GRPC/LowLevel/Server.hs | 4 ++-- core/src/Network/GRPC/Unsafe.chs | 11 ----------- core/src/Network/GRPC/Unsafe/Security.chs | 16 +++++++++++++--- nix/dhall.nix | 1 + nix/proto3-suite.nix | 4 ++-- nix/proto3-wire.nix | 4 ++-- nixpkgs.nix | 6 +++--- release.nix | 12 ++++++++++++ 10 files changed, 41 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 9937467a..4206e656 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ have extended and released under the same [`LICENSE`](./LICENSE) Installation ------------ -**The current version of this library requires gRPC version 1.42.0. Newer versions may work but have not been tested.** +**The current version of this library requires gRPC version 1.45.0. Newer versions may work but have not been tested.** Usage ----- diff --git a/core/src/Network/GRPC/LowLevel/Client.hs b/core/src/Network/GRPC/LowLevel/Client.hs index c78e4255..5f43764f 100644 --- a/core/src/Network/GRPC/LowLevel/Client.hs +++ b/core/src/Network/GRPC/LowLevel/Client.hs @@ -84,19 +84,21 @@ addMetadataCreds c (Just create) = do createChannel :: ClientConfig -> C.GrpcChannelArgs -> IO C.Channel createChannel ClientConfig{..} chanargs = case clientSSLConfig of - Nothing -> C.grpcInsecureChannelCreate e chanargs C.reserved + Nothing -> + C.withInsecureChannelCredentials $ \creds -> + C.grpcChannelCreate e creds chanargs Just (ClientSSLConfig rootCertPath Nothing plugin) -> do rootCert <- mapM B.readFile rootCertPath C.withChannelCredentials rootCert Nothing Nothing $ \creds -> do creds' <- addMetadataCreds creds plugin - C.secureChannelCreate creds' e chanargs C.reserved + C.grpcChannelCreate e creds' chanargs Just (ClientSSLConfig x (Just (ClientSSLKeyCertPair y z)) plugin) -> do rootCert <- mapM B.readFile x privKey <- Just <$> B.readFile y clientCert <- Just <$> B.readFile z C.withChannelCredentials rootCert privKey clientCert $ \creds -> do creds' <- addMetadataCreds creds plugin - C.secureChannelCreate creds' e chanargs C.reserved + C.grpcChannelCreate e creds' chanargs where (Endpoint e) = clientServerEndpoint createClient :: GRPC -> ClientConfig -> IO Client diff --git a/core/src/Network/GRPC/LowLevel/Server.hs b/core/src/Network/GRPC/LowLevel/Server.hs index fc718a4c..bb0290c6 100644 --- a/core/src/Network/GRPC/LowLevel/Server.hs +++ b/core/src/Network/GRPC/LowLevel/Server.hs @@ -143,7 +143,7 @@ serverEndpoint ServerConfig{..} = endpoint host port addPort :: C.Server -> ServerConfig -> IO Int addPort server conf@ServerConfig{..} = case sslConfig of - Nothing -> C.grpcServerAddInsecureHttp2Port server e + Nothing -> C.withInsecureServerCredentials $ C.grpcServerAddHttp2Port server e Just ServerSSLConfig{..} -> do crc <- mapM B.readFile clientRootCert spk <- B.readFile serverPrivateKey @@ -152,7 +152,7 @@ addPort server conf@ServerConfig{..} = case customMetadataProcessor of Just p -> C.setMetadataProcessor creds p Nothing -> return () - C.serverAddSecureHttp2Port server e creds + C.grpcServerAddHttp2Port server e creds where e = unEndpoint $ serverEndpoint conf startServer :: GRPC -> ServerConfig -> IO Server diff --git a/core/src/Network/GRPC/Unsafe.chs b/core/src/Network/GRPC/Unsafe.chs index 8967537e..9823ecee 100644 --- a/core/src/Network/GRPC/Unsafe.chs +++ b/core/src/Network/GRPC/Unsafe.chs @@ -189,14 +189,6 @@ castPeek p = do useAsCString* `ByteString', useAsCString* `ByteString', `CTimeSpecPtr',unReserved `Reserved'} -> `Call'#} --- | Create a channel (on the client) to the server. The first argument is --- host and port, e.g. @"localhost:50051"@. The gRPC docs say that most clients --- are expected to pass a 'nullPtr' for the 'ChannelArgsPtr'. We currently don't --- expose any functions for creating channel args, since they are entirely --- undocumented. -{#fun grpc_insecure_channel_create as ^ - {useAsCString* `ByteString', `GrpcChannelArgs', unReserved `Reserved'} -> `Channel'#} - {#fun grpc_channel_register_call as ^ {`Channel', useAsCString* `ByteString',useAsCString* `ByteString',unReserved `Reserved'} -> `CallHandle' CallHandle#} @@ -258,9 +250,6 @@ getPeerPeek cstr = do {#fun grpc_server_register_completion_queue as ^ {`Server', `CompletionQueue', unReserved `Reserved'} -> `()'#} -{#fun grpc_server_add_insecure_http2_port as ^ - {`Server', useAsCString* `ByteString'} -> `Int'#} - -- | Starts a server. To shut down the server, call these in order: -- 'grpcServerShutdownAndNotify', 'grpcServerCancelAllCalls', -- 'grpcServerDestroy'. After these are done, shut down and destroy the server's diff --git a/core/src/Network/GRPC/Unsafe/Security.chs b/core/src/Network/GRPC/Unsafe/Security.chs index 7de77f18..27096ca6 100644 --- a/core/src/Network/GRPC/Unsafe/Security.chs +++ b/core/src/Network/GRPC/Unsafe/Security.chs @@ -169,6 +169,8 @@ getAuthProperties ctx = withAuthPropertyIterator ctx $ \i -> do {#fun unsafe ssl_credentials_create_internal as ^ {`CString', `CString', `CString'} -> `ChannelCredentials'#} +{#fun insecure_credentials_create as ^ {} -> `ChannelCredentials'#} + sslChannelCredentialsCreate :: Maybe ByteString -> Maybe ByteString -> Maybe ByteString @@ -195,6 +197,9 @@ withChannelCredentials :: Maybe ByteString withChannelCredentials x y z = bracket (sslChannelCredentialsCreate x y z) channelCredentialsRelease +withInsecureChannelCredentials :: (ChannelCredentials -> IO a) -> IO a +withInsecureChannelCredentials = bracket insecureCredentialsCreate channelCredentialsRelease + -- * Call Credentials {#fun call_set_credentials as ^ @@ -219,6 +224,8 @@ withChannelCredentials x y z = bracket (sslChannelCredentialsCreate x y z) `SslClientCertificateRequestType'} -> `ServerCredentials'#} +{#fun insecure_server_credentials_create as ^ {} -> `ServerCredentials'#} + sslServerCredentialsCreate :: Maybe ByteString -- ^ PEM encoding of the client root certificates. -- Can be 'Nothing' if SSL authentication of @@ -252,13 +259,16 @@ withServerCredentials a b c d = bracket (sslServerCredentialsCreate a b c d) -- * Creating Secure Clients/Servers -{#fun server_add_secure_http2_port as ^ +{#fun grpc_server_add_http2_port as ^ {`Server',useAsCString* `ByteString', `ServerCredentials'} -> `Int'#} -{#fun secure_channel_create as ^ - {`ChannelCredentials',useAsCString* `ByteString', `GrpcChannelArgs', unReserved `Reserved'} +{#fun grpc_channel_create as ^ + {useAsCString* `ByteString', `ChannelCredentials', `GrpcChannelArgs'} -> `Channel'#} +withInsecureServerCredentials :: (ServerCredentials -> IO a) -> IO a +withInsecureServerCredentials = bracket insecureServerCredentialsCreate serverCredentialsRelease + -- * Custom metadata processing -- server side -- | Type synonym for the raw function pointer we pass to C to handle custom diff --git a/nix/dhall.nix b/nix/dhall.nix index 978b3c5b..78e64197 100644 --- a/nix/dhall.nix +++ b/nix/dhall.nix @@ -20,6 +20,7 @@ mkDerivation { sha256 = "f3e95cfa0ef1a89d5ca29591b7925db51551150a27f3fd02717ce69699e8e03c"; revision = "2"; editedCabalFile = "02z0jmzzp20yj46iz6i384xwc6k2anxb33smvc4yhpmhqjs0aq8a"; + jailbreak = true; isLibrary = true; isExecutable = true; enableSeparateDataOutput = true; diff --git a/nix/proto3-suite.nix b/nix/proto3-suite.nix index 72fc0d77..d76f6f11 100644 --- a/nix/proto3-suite.nix +++ b/nix/proto3-suite.nix @@ -15,8 +15,8 @@ mkDerivation { version = "0.6.0"; src = fetchgit { url = "https://github.com/awakesecurity/proto3-suite.git"; - sha256 = "1bvivy1rw84gln3kvb704wcsaz8l5xmgfibbbammbkmnjcgfs1y5"; - rev = "1f2c156b1178599d3853dac941beb3f29e2bdf5e"; + sha256 = "sha256-1a1ZHlvvtE1urvDL7n984OQ5gbro26RnKAjvDCH/2fs="; + rev = "9f7daef66ba6dfc9574039b1d206c5df126d4b39"; fetchSubmodules = true; }; isLibrary = true; diff --git a/nix/proto3-wire.nix b/nix/proto3-wire.nix index 6922ac52..c2f17054 100644 --- a/nix/proto3-wire.nix +++ b/nix/proto3-wire.nix @@ -9,8 +9,8 @@ mkDerivation { version = "1.4.1"; src = fetchgit { url = "https://github.com/awakesecurity/proto3-wire.git"; - sha256 = "189dzkxdwnfscq8ylfalxkh95x7kkjlawz9wqkwbdblg5a5k1y7i"; - rev = "13962d58dbfb3cfbb539702746afe94ec02189ce"; + sha256 = "sha256-g15oAYmhfv8DVgmQTZkcCgOYRFkxl2PQi30qXXXhBLs="; + rev = "ee6ca644eef86cc5f31da85fb48e10b20ab0e1a1"; fetchSubmodules = true; }; libraryHaskellDepends = [ diff --git a/nixpkgs.nix b/nixpkgs.nix index 175ff216..332a613b 100644 --- a/nixpkgs.nix +++ b/nixpkgs.nix @@ -7,7 +7,7 @@ # The SHA256 will be printed as the last line of stdout. import (builtins.fetchTarball { - # nixos-21.11 as on 2023-06-15 - url = "https://github.com/NixOS/nixpkgs/archive/eabc38219184cc3e04a974fe31857d8e0eac098d.tar.gz"; - sha256 = "04ffwp2gzq0hhz7siskw6qh9ys8ragp7285vi1zh8xjksxn1msc5"; + # "master" as on 2022-04-22 + url = "https://github.com/NixOS/nixpkgs/archive/ed3cc9672ad507ca4d00e15b35f3d24edd1dff6c.tar.gz"; + sha256 = "1bn55f20kqpdcfz0gsn9j6cyw617izrnwb4yw33bgqhyxlabb4q0"; }) diff --git a/release.nix b/release.nix index 7c2a5fef..bb6c01da 100644 --- a/release.nix +++ b/release.nix @@ -70,6 +70,14 @@ let haskellPackages = pkgsOld.haskellPackages.override { overrides = haskellPackagesNew: haskellPackagesOld: rec { + data-diverse = + pkgsNew.haskell.lib.overrideCabal haskellPackagesOld.data-diverse (old: { + broken = assert !old.broken -> + builtins.trace "remove the data-diverse override in release.nix" false; + false; + doCheck = false; + }); + dhall = haskellPackagesNew.callPackage ./nix/dhall.nix { }; @@ -151,6 +159,10 @@ let (oldDerivation.patches or [ ]) ++ [ ./tests/tests.patch ]; postPatch = (oldDerivation.postPatch or "") + '' + for bin in tests/*.sh; do + chmod a+x "$bin" + done + patchShebangs tests substituteInPlace tests/simple-client.sh \ --replace @makeWrapper@ ${pkgsNew.makeWrapper} \