1# Copyright 2015 gRPC authors. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15require 'spec_helper' 16 17def create_channel_creds 18 test_root = File.join(File.dirname(__FILE__), 'testdata') 19 files = ['ca.pem', 'client.key', 'client.pem'] 20 creds = files.map { |f| File.open(File.join(test_root, f)).read } 21 GRPC::Core::ChannelCredentials.new(creds[0], creds[1], creds[2]) 22end 23 24def client_cert 25 test_root = File.join(File.dirname(__FILE__), 'testdata') 26 cert = File.open(File.join(test_root, 'client.pem')).read 27 fail unless cert.is_a?(String) 28 cert 29end 30 31def create_server_creds 32 test_root = File.join(File.dirname(__FILE__), 'testdata') 33 GRPC.logger.info("test root: #{test_root}") 34 files = ['ca.pem', 'server1.key', 'server1.pem'] 35 creds = files.map { |f| File.open(File.join(test_root, f)).read } 36 GRPC::Core::ServerCredentials.new( 37 creds[0], 38 [{ private_key: creds[1], cert_chain: creds[2] }], 39 true) # force client auth 40end 41 42# a test service that checks the cert of its peer 43class SslTestService 44 include GRPC::GenericService 45 rpc :an_rpc, EchoMsg, EchoMsg 46 rpc :a_client_streaming_rpc, stream(EchoMsg), EchoMsg 47 rpc :a_server_streaming_rpc, EchoMsg, stream(EchoMsg) 48 rpc :a_bidi_rpc, stream(EchoMsg), stream(EchoMsg) 49 50 def check_peer_cert(call) 51 error_msg = "want:\n#{client_cert}\n\ngot:\n#{call.peer_cert}" 52 fail(error_msg) unless call.peer_cert == client_cert 53 end 54 55 def an_rpc(req, call) 56 check_peer_cert(call) 57 req 58 end 59 60 def a_client_streaming_rpc(call) 61 check_peer_cert(call) 62 call.each_remote_read.each { |r| GRPC.logger.info(r) } 63 EchoMsg.new 64 end 65 66 def a_server_streaming_rpc(_, call) 67 check_peer_cert(call) 68 [EchoMsg.new, EchoMsg.new] 69 end 70 71 def a_bidi_rpc(requests, call) 72 check_peer_cert(call) 73 requests.each { |r| GRPC.logger.info(r) } 74 [EchoMsg.new, EchoMsg.new] 75 end 76end 77 78SslTestServiceStub = SslTestService.rpc_stub_class 79 80describe 'client-server auth' do 81 RpcServer = GRPC::RpcServer 82 83 before(:all) do 84 server_opts = { 85 poll_period: 1 86 } 87 @srv = new_rpc_server_for_testing(**server_opts) 88 port = @srv.add_http2_port('0.0.0.0:0', create_server_creds) 89 @srv.handle(SslTestService) 90 @srv_thd = Thread.new { @srv.run } 91 @srv.wait_till_running 92 93 client_opts = { 94 channel_args: { 95 GRPC::Core::Channel::SSL_TARGET => 'foo.test.google.fr' 96 } 97 } 98 @stub = SslTestServiceStub.new("localhost:#{port}", 99 create_channel_creds, 100 **client_opts) 101 end 102 103 after(:all) do 104 expect(@srv.stopped?).to be(false) 105 @srv.stop 106 @srv_thd.join 107 end 108 109 it 'client-server auth with unary RPCs' do 110 @stub.an_rpc(EchoMsg.new) 111 end 112 113 it 'client-server auth with client streaming RPCs' do 114 @stub.a_client_streaming_rpc([EchoMsg.new, EchoMsg.new]) 115 end 116 117 it 'client-server auth with server streaming RPCs' do 118 responses = @stub.a_server_streaming_rpc(EchoMsg.new) 119 responses.each { |r| GRPC.logger.info(r) } 120 end 121 122 it 'client-server auth with bidi RPCs' do 123 responses = @stub.a_bidi_rpc([EchoMsg.new, EchoMsg.new]) 124 responses.each { |r| GRPC.logger.info(r) } 125 end 126end 127