• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 //
3 // Copyright 2015-2016 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 "src/core/lib/security/credentials/composite/composite_credentials.h"
20 
21 #include <grpc/support/port_platform.h>
22 
23 #include <cstring>
24 #include <memory>
25 #include <vector>
26 
27 #include "absl/log/check.h"
28 #include "absl/strings/str_cat.h"
29 #include "absl/strings/str_join.h"
30 #include "src/core/lib/debug/trace.h"
31 #include "src/core/lib/promise/try_seq.h"
32 #include "src/core/lib/transport/metadata_batch.h"
33 #include "src/core/util/ref_counted_ptr.h"
34 
35 //
36 // grpc_composite_channel_credentials
37 //
38 
Type()39 grpc_core::UniqueTypeName grpc_composite_channel_credentials::Type() {
40   static grpc_core::UniqueTypeName::Factory kFactory("Composite");
41   return kFactory.Create();
42 }
43 
44 // -- Composite call credentials. --
45 
46 grpc_core::ArenaPromise<absl::StatusOr<grpc_core::ClientMetadataHandle>>
GetRequestMetadata(grpc_core::ClientMetadataHandle initial_metadata,const grpc_call_credentials::GetRequestMetadataArgs * args)47 grpc_composite_call_credentials::GetRequestMetadata(
48     grpc_core::ClientMetadataHandle initial_metadata,
49     const grpc_call_credentials::GetRequestMetadataArgs* args) {
50   auto self = Ref();
51   return TrySeqIter(
52       inner_.begin(), inner_.end(), std::move(initial_metadata),
53       [self, args](const grpc_core::RefCountedPtr<grpc_call_credentials>& creds,
54                    grpc_core::ClientMetadataHandle initial_metadata) {
55         return creds->GetRequestMetadata(std::move(initial_metadata), args);
56       });
57 }
58 
Type()59 grpc_core::UniqueTypeName grpc_composite_call_credentials::Type() {
60   static grpc_core::UniqueTypeName::Factory kFactory("Composite");
61   return kFactory.Create();
62 }
63 
debug_string()64 std::string grpc_composite_call_credentials::debug_string() {
65   std::vector<std::string> outputs;
66   for (auto& inner_cred : inner_) {
67     outputs.emplace_back(inner_cred->debug_string());
68   }
69   return absl::StrCat("CompositeCallCredentials{", absl::StrJoin(outputs, ","),
70                       "}");
71 }
72 
get_creds_array_size(const grpc_call_credentials * creds,bool is_composite)73 static size_t get_creds_array_size(const grpc_call_credentials* creds,
74                                    bool is_composite) {
75   return is_composite
76              ? static_cast<const grpc_composite_call_credentials*>(creds)
77                    ->inner()
78                    .size()
79              : 1;
80 }
81 
push_to_inner(grpc_core::RefCountedPtr<grpc_call_credentials> creds,bool is_composite)82 void grpc_composite_call_credentials::push_to_inner(
83     grpc_core::RefCountedPtr<grpc_call_credentials> creds, bool is_composite) {
84   if (!is_composite) {
85     inner_.push_back(std::move(creds));
86     return;
87   }
88   auto composite_creds =
89       static_cast<grpc_composite_call_credentials*>(creds.get());
90   for (size_t i = 0; i < composite_creds->inner().size(); ++i) {
91     inner_.push_back(composite_creds->inner_[i]);
92   }
93 }
94 
grpc_composite_call_credentials(grpc_core::RefCountedPtr<grpc_call_credentials> creds1,grpc_core::RefCountedPtr<grpc_call_credentials> creds2)95 grpc_composite_call_credentials::grpc_composite_call_credentials(
96     grpc_core::RefCountedPtr<grpc_call_credentials> creds1,
97     grpc_core::RefCountedPtr<grpc_call_credentials> creds2) {
98   const bool creds1_is_composite =
99       creds1->type() == grpc_composite_call_credentials::Type();
100   const bool creds2_is_composite =
101       creds2->type() == grpc_composite_call_credentials::Type();
102   const size_t size = get_creds_array_size(creds1.get(), creds1_is_composite) +
103                       get_creds_array_size(creds2.get(), creds2_is_composite);
104   inner_.reserve(size);
105   push_to_inner(std::move(creds1), creds1_is_composite);
106   push_to_inner(std::move(creds2), creds2_is_composite);
107   min_security_level_ = GRPC_SECURITY_NONE;
108   for (size_t i = 0; i < inner_.size(); ++i) {
109     if (static_cast<int>(min_security_level_) <
110         static_cast<int>(inner_[i]->min_security_level())) {
111       min_security_level_ = inner_[i]->min_security_level();
112     }
113   }
114 }
115 
116 static grpc_core::RefCountedPtr<grpc_call_credentials>
composite_call_credentials_create(grpc_core::RefCountedPtr<grpc_call_credentials> creds1,grpc_core::RefCountedPtr<grpc_call_credentials> creds2)117 composite_call_credentials_create(
118     grpc_core::RefCountedPtr<grpc_call_credentials> creds1,
119     grpc_core::RefCountedPtr<grpc_call_credentials> creds2) {
120   return grpc_core::MakeRefCounted<grpc_composite_call_credentials>(
121       std::move(creds1), std::move(creds2));
122 }
123 
grpc_composite_call_credentials_create(grpc_call_credentials * creds1,grpc_call_credentials * creds2,void * reserved)124 grpc_call_credentials* grpc_composite_call_credentials_create(
125     grpc_call_credentials* creds1, grpc_call_credentials* creds2,
126     void* reserved) {
127   GRPC_TRACE_LOG(api, INFO)
128       << "grpc_composite_call_credentials_create(creds1=" << creds1
129       << ", creds2=" << creds2 << ", reserved=" << reserved << ")";
130   CHECK_EQ(reserved, nullptr);
131   CHECK_NE(creds1, nullptr);
132   CHECK_NE(creds2, nullptr);
133 
134   return composite_call_credentials_create(creds1->Ref(), creds2->Ref())
135       .release();
136 }
137 
138 // -- Composite channel credentials. --
139 
140 grpc_core::RefCountedPtr<grpc_channel_security_connector>
create_security_connector(grpc_core::RefCountedPtr<grpc_call_credentials> call_creds,const char * target,grpc_core::ChannelArgs * args)141 grpc_composite_channel_credentials::create_security_connector(
142     grpc_core::RefCountedPtr<grpc_call_credentials> call_creds,
143     const char* target, grpc_core::ChannelArgs* args) {
144   CHECK(inner_creds_ != nullptr);
145   CHECK(call_creds_ != nullptr);
146   // If we are passed a call_creds, create a call composite to pass it
147   // downstream.
148   if (call_creds != nullptr) {
149     return inner_creds_->create_security_connector(
150         composite_call_credentials_create(call_creds_, std::move(call_creds)),
151         target, args);
152   } else {
153     return inner_creds_->create_security_connector(call_creds_, target, args);
154   }
155 }
156 
grpc_composite_channel_credentials_create(grpc_channel_credentials * channel_creds,grpc_call_credentials * call_creds,void * reserved)157 grpc_channel_credentials* grpc_composite_channel_credentials_create(
158     grpc_channel_credentials* channel_creds, grpc_call_credentials* call_creds,
159     void* reserved) {
160   CHECK(channel_creds != nullptr && call_creds != nullptr &&
161         reserved == nullptr);
162   GRPC_TRACE_LOG(api, INFO)
163       << "grpc_composite_channel_credentials_create(channel_creds="
164       << channel_creds << ", call_creds=" << call_creds
165       << ", reserved=" << reserved << ")";
166   return new grpc_composite_channel_credentials(channel_creds->Ref(),
167                                                 call_creds->Ref());
168 }
169