1 //
2 //
3 // Copyright 2018 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 <grpc/support/port_platform.h>
20 
21 #include <grpc/grpc_security.h>
22 #include <grpc/support/alloc.h>
23 #include <grpc/support/log.h>
24 #include <grpc/support/string_util.h>
25 
26 #include "src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h"
27 #include "src/core/tsi/alts/handshaker/transport_security_common_api.h"
28 
29 static grpc_alts_credentials_options* alts_client_options_copy(
30     const grpc_alts_credentials_options* options);
31 
32 static void alts_client_options_destroy(grpc_alts_credentials_options* options);
33 
target_service_account_create(const char * service_account)34 static target_service_account* target_service_account_create(
35     const char* service_account) {
36   if (service_account == nullptr) {
37     return nullptr;
38   }
39   auto* sa = static_cast<target_service_account*>(
40       gpr_zalloc(sizeof(target_service_account)));
41   sa->data = gpr_strdup(service_account);
42   return sa;
43 }
44 
grpc_alts_credentials_client_options_add_target_service_account(grpc_alts_credentials_options * options,const char * service_account)45 void grpc_alts_credentials_client_options_add_target_service_account(
46     grpc_alts_credentials_options* options, const char* service_account) {
47   if (options == nullptr || service_account == nullptr) {
48     gpr_log(
49         GPR_ERROR,
50         "Invalid nullptr arguments to "
51         "grpc_alts_credentials_client_options_add_target_service_account()");
52     return;
53   }
54   auto client_options =
55       reinterpret_cast<grpc_alts_credentials_client_options*>(options);
56   target_service_account* node = target_service_account_create(service_account);
57   node->next = client_options->target_account_list_head;
58   client_options->target_account_list_head = node;
59 }
60 
target_service_account_destroy(target_service_account * service_account)61 static void target_service_account_destroy(
62     target_service_account* service_account) {
63   if (service_account == nullptr) {
64     return;
65   }
66   gpr_free(service_account->data);
67   gpr_free(service_account);
68 }
69 
70 static const grpc_alts_credentials_options_vtable vtable = {
71     alts_client_options_copy, alts_client_options_destroy};
72 
grpc_alts_credentials_client_options_create(void)73 grpc_alts_credentials_options* grpc_alts_credentials_client_options_create(
74     void) {
75   auto client_options = static_cast<grpc_alts_credentials_client_options*>(
76       gpr_zalloc(sizeof(grpc_alts_credentials_client_options)));
77   client_options->base.vtable = &vtable;
78   return &client_options->base;
79 }
80 
alts_client_options_copy(const grpc_alts_credentials_options * options)81 static grpc_alts_credentials_options* alts_client_options_copy(
82     const grpc_alts_credentials_options* options) {
83   if (options == nullptr) {
84     return nullptr;
85   }
86   grpc_alts_credentials_options* new_options =
87       grpc_alts_credentials_client_options_create();
88   auto new_client_options =
89       reinterpret_cast<grpc_alts_credentials_client_options*>(new_options);
90   // Copy target service accounts.
91   target_service_account* prev = nullptr;
92   auto node =
93       (reinterpret_cast<const grpc_alts_credentials_client_options*>(options))
94           ->target_account_list_head;
95   while (node != nullptr) {
96     target_service_account* new_node =
97         target_service_account_create(node->data);
98     if (prev == nullptr) {
99       new_client_options->target_account_list_head = new_node;
100     } else {
101       prev->next = new_node;
102     }
103     prev = new_node;
104     node = node->next;
105   }
106   // Copy rpc protocol versions.
107   grpc_gcp_rpc_protocol_versions_copy(&options->rpc_versions,
108                                       &new_options->rpc_versions);
109   return new_options;
110 }
111 
alts_client_options_destroy(grpc_alts_credentials_options * options)112 static void alts_client_options_destroy(
113     grpc_alts_credentials_options* options) {
114   if (options == nullptr) {
115     return;
116   }
117   auto* client_options =
118       reinterpret_cast<grpc_alts_credentials_client_options*>(options);
119   target_service_account* node = client_options->target_account_list_head;
120   while (node != nullptr) {
121     target_service_account* next_node = node->next;
122     target_service_account_destroy(node);
123     node = next_node;
124   }
125 }
126