# Copyright 2015 gRPC authors.
|
#
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
# you may not use this file except in compliance with the License.
|
# You may obtain a copy of the License at
|
#
|
# http://www.apache.org/licenses/LICENSE-2.0
|
#
|
# Unless required by applicable law or agreed to in writing, software
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# See the License for the specific language governing permissions and
|
# limitations under the License.
|
|
require 'spec_helper'
|
|
def create_channel_creds
|
test_root = File.join(File.dirname(__FILE__), 'testdata')
|
files = ['ca.pem', 'client.key', 'client.pem']
|
creds = files.map { |f| File.open(File.join(test_root, f)).read }
|
GRPC::Core::ChannelCredentials.new(creds[0], creds[1], creds[2])
|
end
|
|
def client_cert
|
test_root = File.join(File.dirname(__FILE__), 'testdata')
|
cert = File.open(File.join(test_root, 'client.pem')).read
|
fail unless cert.is_a?(String)
|
cert
|
end
|
|
def create_server_creds
|
test_root = File.join(File.dirname(__FILE__), 'testdata')
|
GRPC.logger.info("test root: #{test_root}")
|
files = ['ca.pem', 'server1.key', 'server1.pem']
|
creds = files.map { |f| File.open(File.join(test_root, f)).read }
|
GRPC::Core::ServerCredentials.new(
|
creds[0],
|
[{ private_key: creds[1], cert_chain: creds[2] }],
|
true) # force client auth
|
end
|
|
# a test service that checks the cert of its peer
|
class SslTestService
|
include GRPC::GenericService
|
rpc :an_rpc, EchoMsg, EchoMsg
|
rpc :a_client_streaming_rpc, stream(EchoMsg), EchoMsg
|
rpc :a_server_streaming_rpc, EchoMsg, stream(EchoMsg)
|
rpc :a_bidi_rpc, stream(EchoMsg), stream(EchoMsg)
|
|
def check_peer_cert(call)
|
error_msg = "want:\n#{client_cert}\n\ngot:\n#{call.peer_cert}"
|
fail(error_msg) unless call.peer_cert == client_cert
|
end
|
|
def an_rpc(req, call)
|
check_peer_cert(call)
|
req
|
end
|
|
def a_client_streaming_rpc(call)
|
check_peer_cert(call)
|
call.each_remote_read.each { |r| GRPC.logger.info(r) }
|
EchoMsg.new
|
end
|
|
def a_server_streaming_rpc(_, call)
|
check_peer_cert(call)
|
[EchoMsg.new, EchoMsg.new]
|
end
|
|
def a_bidi_rpc(requests, call)
|
check_peer_cert(call)
|
requests.each { |r| GRPC.logger.info(r) }
|
[EchoMsg.new, EchoMsg.new]
|
end
|
end
|
|
SslTestServiceStub = SslTestService.rpc_stub_class
|
|
describe 'client-server auth' do
|
RpcServer = GRPC::RpcServer
|
|
before(:all) do
|
server_opts = {
|
poll_period: 1
|
}
|
@srv = new_rpc_server_for_testing(**server_opts)
|
port = @srv.add_http2_port('0.0.0.0:0', create_server_creds)
|
@srv.handle(SslTestService)
|
@srv_thd = Thread.new { @srv.run }
|
@srv.wait_till_running
|
|
client_opts = {
|
channel_args: {
|
GRPC::Core::Channel::SSL_TARGET => 'foo.test.google.fr'
|
}
|
}
|
@stub = SslTestServiceStub.new("localhost:#{port}",
|
create_channel_creds,
|
**client_opts)
|
end
|
|
after(:all) do
|
expect(@srv.stopped?).to be(false)
|
@srv.stop
|
@srv_thd.join
|
end
|
|
it 'client-server auth with unary RPCs' do
|
@stub.an_rpc(EchoMsg.new)
|
end
|
|
it 'client-server auth with client streaming RPCs' do
|
@stub.a_client_streaming_rpc([EchoMsg.new, EchoMsg.new])
|
end
|
|
it 'client-server auth with server streaming RPCs' do
|
responses = @stub.a_server_streaming_rpc(EchoMsg.new)
|
responses.each { |r| GRPC.logger.info(r) }
|
end
|
|
it 'client-server auth with bidi RPCs' do
|
responses = @stub.a_bidi_rpc([EchoMsg.new, EchoMsg.new])
|
responses.each { |r| GRPC.logger.info(r) }
|
end
|
end
|