Skip to content

Commit

Permalink
Expose google cgrpc credential mode
Browse files Browse the repository at this point in the history
  • Loading branch information
bmhatfield committed Jul 30, 2018
1 parent 240466e commit b4414b8
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 6 deletions.
4 changes: 4 additions & 0 deletions Sources/CgRPC/shim/cgrpc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
16 changes: 16 additions & 0 deletions Sources/CgRPC/shim/channel.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
26 changes: 21 additions & 5 deletions Sources/SwiftGRPC/Core/Channel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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()
Expand All @@ -136,19 +152,19 @@ 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)

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
Expand All @@ -160,7 +176,7 @@ private extension Channel {
}
}
}

func shutdown() {
completionQueue.shutdown()
}
Expand Down
20 changes: 19 additions & 1 deletion Sources/SwiftGRPC/Runtime/ServiceClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down

0 comments on commit b4414b8

Please sign in to comment.