1 /*
2 *
3 * Copyright 2019 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19 #include "upb/upb.hpp"
20
21 #include <grpcpp/security/alts_context.h>
22 #include <grpcpp/security/alts_util.h>
23 #include <grpcpp/security/auth_context.h>
24 #include <gtest/gtest.h>
25
26 #include "src/core/tsi/alts/handshaker/alts_tsi_handshaker.h"
27 #include "src/cpp/common/secure_auth_context.h"
28 #include "src/proto/grpc/gcp/altscontext.upb.h"
29 #include "test/cpp/util/string_ref_helper.h"
30
31 namespace grpc {
32 namespace {
33
TEST(AltsUtilTest,NullAuthContext)34 TEST(AltsUtilTest, NullAuthContext) {
35 std::unique_ptr<experimental::AltsContext> alts_context =
36 experimental::GetAltsContextFromAuthContext(nullptr);
37 EXPECT_EQ(alts_context, nullptr);
38 }
39
TEST(AltsUtilTest,EmptyAuthContext)40 TEST(AltsUtilTest, EmptyAuthContext) {
41 grpc_core::RefCountedPtr<grpc_auth_context> ctx =
42 grpc_core::MakeRefCounted<grpc_auth_context>(nullptr);
43 const std::shared_ptr<AuthContext> auth_context(
44 new SecureAuthContext(ctx.get()));
45 std::unique_ptr<experimental::AltsContext> alts_context =
46 experimental::GetAltsContextFromAuthContext(auth_context);
47 EXPECT_EQ(alts_context, nullptr);
48 }
49
TEST(AltsUtilTest,AuthContextWithMoreThanOneAltsContext)50 TEST(AltsUtilTest, AuthContextWithMoreThanOneAltsContext) {
51 grpc_core::RefCountedPtr<grpc_auth_context> ctx =
52 grpc_core::MakeRefCounted<grpc_auth_context>(nullptr);
53 const std::shared_ptr<AuthContext> auth_context(
54 new SecureAuthContext(ctx.get()));
55 ctx.reset();
56 auth_context->AddProperty(TSI_ALTS_CONTEXT, "context1");
57 auth_context->AddProperty(TSI_ALTS_CONTEXT, "context2");
58 std::unique_ptr<experimental::AltsContext> alts_context =
59 experimental::GetAltsContextFromAuthContext(auth_context);
60 EXPECT_EQ(alts_context, nullptr);
61 }
62
TEST(AltsUtilTest,AuthContextWithBadAltsContext)63 TEST(AltsUtilTest, AuthContextWithBadAltsContext) {
64 grpc_core::RefCountedPtr<grpc_auth_context> ctx =
65 grpc_core::MakeRefCounted<grpc_auth_context>(nullptr);
66 const std::shared_ptr<AuthContext> auth_context(
67 new SecureAuthContext(ctx.get()));
68 ctx.reset();
69 auth_context->AddProperty(TSI_ALTS_CONTEXT,
70 "bad context string serialization");
71 std::unique_ptr<experimental::AltsContext> alts_context =
72 experimental::GetAltsContextFromAuthContext(auth_context);
73 EXPECT_EQ(alts_context, nullptr);
74 }
75
TEST(AltsUtilTest,AuthContextWithGoodAltsContextWithoutRpcVersions)76 TEST(AltsUtilTest, AuthContextWithGoodAltsContextWithoutRpcVersions) {
77 grpc_core::RefCountedPtr<grpc_auth_context> ctx =
78 grpc_core::MakeRefCounted<grpc_auth_context>(nullptr);
79 const std::shared_ptr<AuthContext> auth_context(
80 new SecureAuthContext(ctx.get()));
81 ctx.reset();
82 std::string expected_ap("application protocol");
83 std::string expected_rp("record protocol");
84 std::string expected_peer("peer");
85 std::string expected_local("local");
86 grpc_security_level expected_sl = GRPC_INTEGRITY_ONLY;
87 upb::Arena context_arena;
88 grpc_gcp_AltsContext* context = grpc_gcp_AltsContext_new(context_arena.ptr());
89 grpc_gcp_AltsContext_set_application_protocol(
90 context, upb_strview_make(expected_ap.data(), expected_ap.length()));
91 grpc_gcp_AltsContext_set_record_protocol(
92 context, upb_strview_make(expected_rp.data(), expected_rp.length()));
93 grpc_gcp_AltsContext_set_security_level(context, expected_sl);
94 grpc_gcp_AltsContext_set_peer_service_account(
95 context, upb_strview_make(expected_peer.data(), expected_peer.length()));
96 grpc_gcp_AltsContext_set_local_service_account(
97 context,
98 upb_strview_make(expected_local.data(), expected_local.length()));
99 size_t serialized_ctx_length;
100 char* serialized_ctx = grpc_gcp_AltsContext_serialize(
101 context, context_arena.ptr(), &serialized_ctx_length);
102 EXPECT_NE(serialized_ctx, nullptr);
103 auth_context->AddProperty(TSI_ALTS_CONTEXT,
104 string(serialized_ctx, serialized_ctx_length));
105 std::unique_ptr<experimental::AltsContext> alts_context =
106 experimental::GetAltsContextFromAuthContext(auth_context);
107 EXPECT_NE(alts_context, nullptr);
108 EXPECT_EQ(expected_ap, alts_context->application_protocol());
109 EXPECT_EQ(expected_rp, alts_context->record_protocol());
110 EXPECT_EQ(expected_peer, alts_context->peer_service_account());
111 EXPECT_EQ(expected_local, alts_context->local_service_account());
112 EXPECT_EQ(expected_sl, alts_context->security_level());
113 // all rpc versions should be 0 if not set
114 experimental::AltsContext::RpcProtocolVersions rpc_protocol_versions =
115 alts_context->peer_rpc_versions();
116 EXPECT_EQ(0, rpc_protocol_versions.max_rpc_version.major_version);
117 EXPECT_EQ(0, rpc_protocol_versions.max_rpc_version.minor_version);
118 EXPECT_EQ(0, rpc_protocol_versions.min_rpc_version.major_version);
119 EXPECT_EQ(0, rpc_protocol_versions.min_rpc_version.minor_version);
120 }
121
TEST(AltsUtilTest,AuthContextWithGoodAltsContext)122 TEST(AltsUtilTest, AuthContextWithGoodAltsContext) {
123 grpc_core::RefCountedPtr<grpc_auth_context> ctx =
124 grpc_core::MakeRefCounted<grpc_auth_context>(nullptr);
125 const std::shared_ptr<AuthContext> auth_context(
126 new SecureAuthContext(ctx.get()));
127 ctx.reset();
128 upb::Arena context_arena;
129 grpc_gcp_AltsContext* context = grpc_gcp_AltsContext_new(context_arena.ptr());
130 upb::Arena versions_arena;
131 grpc_gcp_RpcProtocolVersions* versions =
132 grpc_gcp_RpcProtocolVersions_new(versions_arena.ptr());
133 upb::Arena max_major_version_arena;
134 grpc_gcp_RpcProtocolVersions_Version* version =
135 grpc_gcp_RpcProtocolVersions_Version_new(max_major_version_arena.ptr());
136 grpc_gcp_RpcProtocolVersions_Version_set_major(version, 10);
137 grpc_gcp_RpcProtocolVersions_set_max_rpc_version(versions, version);
138 grpc_gcp_AltsContext_set_peer_rpc_versions(context, versions);
139 size_t serialized_ctx_length;
140 char* serialized_ctx = grpc_gcp_AltsContext_serialize(
141 context, context_arena.ptr(), &serialized_ctx_length);
142 EXPECT_NE(serialized_ctx, nullptr);
143 auth_context->AddProperty(TSI_ALTS_CONTEXT,
144 string(serialized_ctx, serialized_ctx_length));
145 std::unique_ptr<experimental::AltsContext> alts_context =
146 experimental::GetAltsContextFromAuthContext(auth_context);
147 EXPECT_NE(alts_context, nullptr);
148 EXPECT_EQ("", alts_context->application_protocol());
149 EXPECT_EQ("", alts_context->record_protocol());
150 EXPECT_EQ("", alts_context->peer_service_account());
151 EXPECT_EQ("", alts_context->local_service_account());
152 EXPECT_EQ(GRPC_SECURITY_NONE, alts_context->security_level());
153 experimental::AltsContext::RpcProtocolVersions rpc_protocol_versions =
154 alts_context->peer_rpc_versions();
155 EXPECT_EQ(10, rpc_protocol_versions.max_rpc_version.major_version);
156 EXPECT_EQ(0, rpc_protocol_versions.max_rpc_version.minor_version);
157 EXPECT_EQ(0, rpc_protocol_versions.min_rpc_version.major_version);
158 EXPECT_EQ(0, rpc_protocol_versions.min_rpc_version.minor_version);
159 }
160
TEST(AltsUtilTest,AltsClientAuthzCheck)161 TEST(AltsUtilTest, AltsClientAuthzCheck) {
162 // AltsClientAuthzCheck function should return a permission denied error on
163 // the bad_auth_context, whose internal ALTS context does not exist
164 const std::shared_ptr<AuthContext> bad_auth_context(
165 new SecureAuthContext(nullptr));
166 std::vector<std::string> service_accounts{"client"};
167 grpc::Status status =
168 experimental::AltsClientAuthzCheck(bad_auth_context, service_accounts);
169 EXPECT_EQ(grpc::StatusCode::PERMISSION_DENIED, status.error_code());
170 // AltsClientAuthzCheck function should function normally when the peer name
171 // in ALTS context is listed in service_accounts
172 grpc_core::RefCountedPtr<grpc_auth_context> ctx =
173 grpc_core::MakeRefCounted<grpc_auth_context>(nullptr);
174 const std::shared_ptr<AuthContext> auth_context(
175 new SecureAuthContext(ctx.get()));
176 ctx.reset();
177 std::string peer("good_client");
178 std::vector<std::string> good_service_accounts{"good_client",
179 "good_client_1"};
180 std::vector<std::string> bad_service_accounts{"bad_client", "bad_client_1"};
181 upb::Arena context_arena;
182 grpc_gcp_AltsContext* context = grpc_gcp_AltsContext_new(context_arena.ptr());
183 grpc_gcp_AltsContext_set_peer_service_account(
184 context, upb_strview_make(peer.data(), peer.length()));
185 size_t serialized_ctx_length;
186 char* serialized_ctx = grpc_gcp_AltsContext_serialize(
187 context, context_arena.ptr(), &serialized_ctx_length);
188 EXPECT_NE(serialized_ctx, nullptr);
189 auth_context->AddProperty(TSI_ALTS_CONTEXT,
190 string(serialized_ctx, serialized_ctx_length));
191 grpc::Status good_status =
192 experimental::AltsClientAuthzCheck(auth_context, good_service_accounts);
193 EXPECT_TRUE(good_status.ok());
194 grpc::Status bad_status =
195 experimental::AltsClientAuthzCheck(auth_context, bad_service_accounts);
196 EXPECT_EQ(grpc::StatusCode::PERMISSION_DENIED, bad_status.error_code());
197 }
198
199 } // namespace
200 } // namespace grpc
201
main(int argc,char ** argv)202 int main(int argc, char** argv) {
203 ::testing::InitGoogleTest(&argc, argv);
204 return RUN_ALL_TESTS();
205 }
206