Prechádzať zdrojové kódy

Expose google cgrpc credential mode

Brian Hatfield 7 rokov pred
rodič
commit
b4414b882c

+ 4 - 0
Sources/CgRPC/shim/cgrpc.h

@@ -171,6 +171,10 @@ cgrpc_channel *cgrpc_channel_create_secure(const char *address,
                                            grpc_arg *args,
                                            int num_args);
 
+cgrpc_channel *cgrpc_channel_create_google(const char *address,
+                                          grpc_arg *args,
+                                          int num_args);
+
 void cgrpc_channel_destroy(cgrpc_channel *channel);
 cgrpc_call *cgrpc_channel_create_call(cgrpc_channel *channel,
                                       const char *method,

+ 16 - 0
Sources/CgRPC/shim/channel.c

@@ -63,6 +63,22 @@ cgrpc_channel *cgrpc_channel_create_secure(const char *address,
   return c;
 }
 
+cgrpc_channel *cgrpc_channel_create_google(const char *address,
+                                           grpc_arg *args,
+                                           int num_args) {
+    cgrpc_channel *c = (cgrpc_channel *) malloc(sizeof (cgrpc_channel));
+
+    grpc_channel_args channel_args;
+    channel_args.args = args;
+    channel_args.num_args = num_args;
+
+    grpc_channel_credentials *google_creds = grpc_google_default_credentials_create();
+
+    c->channel = grpc_secure_channel_create(google_creds, address, &channel_args, NULL);
+    c->completion_queue = grpc_completion_queue_create_for_next(NULL);
+    return c;
+}
+
 
 void cgrpc_channel_destroy(cgrpc_channel *c) {
   grpc_channel_destroy(c->channel);

+ 21 - 5
Sources/SwiftGRPC/Core/Channel.swift

@@ -56,6 +56,22 @@ public class Channel {
     completionQueue.run() // start a loop that watches the channel's completion queue
   }
 
+  /// Initializes a gRPC channel
+  ///
+  /// - Parameter address: the address of the server to be called
+  /// - Parameter arguments: list of channel configuration options
+  public init(googleAddress: String, arguments: [Argument] = []) {
+    gRPC.initialize()
+    host = googleAddress
+    let argumentWrappers = arguments.map { $0.toCArg() }
+    var argumentValues = argumentWrappers.map { $0.wrapped }
+
+    underlyingChannel = cgrpc_channel_create_google(googleAddress, &argumentValues, Int32(arguments.count))
+
+    completionQueue = CompletionQueue(underlyingCompletionQueue: cgrpc_channel_completion_queue(underlyingChannel), name: "Client")
+    completionQueue.run() // start a loop that watches the channel's completion queue
+  }
+
   /// Initializes a gRPC channel
   ///
   /// - Parameter address: the address of the server to be called
@@ -116,7 +132,7 @@ private extension Channel {
     private let underlyingCompletionQueue: UnsafeMutableRawPointer
     private let callback: (ConnectivityState) -> Void
     private var lastState: ConnectivityState
-    
+
     init(underlyingChannel: UnsafeMutableRawPointer, currentState: ConnectivityState, callback: @escaping (ConnectivityState) -> ()) {
       self.underlyingChannel = underlyingChannel
       self.underlyingCompletionQueue = cgrpc_completion_queue_create_for_next()
@@ -136,7 +152,7 @@ private extension Channel {
       spinloopThreadQueue.async {
         while true  {
           guard let underlyingState = self.lastState.underlyingState else { return }
-          
+
           let deadline: TimeInterval = 0.2
           cgrpc_channel_watch_connectivity_state(self.underlyingChannel, self.underlyingCompletionQueue, underlyingState, deadline, nil)
           let event = self.completionQueue.wait(timeout: deadline)
@@ -144,11 +160,11 @@ private extension Channel {
           switch event.type {
           case .complete:
             let newState = ConnectivityState.connectivityState(cgrpc_channel_check_connectivity_state(self.underlyingChannel, 0))
-            
+
             if newState != self.lastState {
               self.callback(newState)
             }
-            
+
             self.lastState = newState
           case .queueTimeout:
             continue
@@ -160,7 +176,7 @@ private extension Channel {
         }
       }
     }
-    
+
     func shutdown() {
       completionQueue.shutdown()
     }

+ 19 - 1
Sources/SwiftGRPC/Runtime/ServiceClient.swift

@@ -60,7 +60,25 @@ open class ServiceClientBase: ServiceClient {
     self.channel = channel
     metadata = Metadata()
   }
-  
+
+  /// Create a client with Google credentials.
+  /// - Parameter googleApi: the name of the Google API service (e.g. "cloudkms" in "cloudkms.googleapis.com")
+  /// - Parameter arguments: list of channel configuration options
+  ///
+  /// Note: cgRPC's `grpc_google_default_credentials_create` doesn't accept a root pem argument.
+  /// To override: `export GRPC_DEFAULT_SSL_ROOTS_FILE_PATH=/path/to/your/root/cert.pem`
+  required public init(googleApi: String, arguments: [Channel.Argument] = []) {
+    gRPC.initialize()
+
+    // Force the address of the Google API to account for the security concern mentioned in
+    // Sources/CgRPC/include/grpc/grpc_security.h:
+    //    WARNING: Do NOT use this credentials to connect to a non-google service as
+    //    this could result in an oauth2 token leak.
+    let address = googleApi + ".googleapis.com"
+    channel = Channel(googleAddress: address, arguments: arguments)
+    metadata = Metadata()
+  }
+
   /// Create a client that makes secure connections with a custom certificate.
   required public init(address: String, certificates: String, clientCertificates: String? = nil, clientKey: String? = nil, arguments: [Channel.Argument] = []) {
     gRPC.initialize()