1 /* 2 * 3 * Copyright 2015 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 "src/core/lib/security/credentials/credentials.h" 22 23 #include <stdio.h> 24 #include <string.h> 25 26 #include "src/core/lib/channel/channel_args.h" 27 #include "src/core/lib/gpr/string.h" 28 #include "src/core/lib/http/httpcli.h" 29 #include "src/core/lib/http/parser.h" 30 #include "src/core/lib/iomgr/executor.h" 31 #include "src/core/lib/json/json.h" 32 #include "src/core/lib/surface/api_trace.h" 33 34 #include <grpc/support/alloc.h> 35 #include <grpc/support/log.h> 36 #include <grpc/support/string_util.h> 37 #include <grpc/support/sync.h> 38 #include <grpc/support/time.h> 39 40 /* -- Common. -- */ 41 42 grpc_credentials_metadata_request* grpc_credentials_metadata_request_create( 43 grpc_call_credentials* creds) { 44 grpc_credentials_metadata_request* r = 45 static_cast<grpc_credentials_metadata_request*>( 46 gpr_zalloc(sizeof(grpc_credentials_metadata_request))); 47 r->creds = grpc_call_credentials_ref(creds); 48 return r; 49 } 50 51 void grpc_credentials_metadata_request_destroy( 52 grpc_credentials_metadata_request* r) { 53 grpc_call_credentials_unref(r->creds); 54 grpc_http_response_destroy(&r->response); 55 gpr_free(r); 56 } 57 58 grpc_channel_credentials* grpc_channel_credentials_ref( 59 grpc_channel_credentials* creds) { 60 if (creds == nullptr) return nullptr; 61 gpr_ref(&creds->refcount); 62 return creds; 63 } 64 65 void grpc_channel_credentials_unref(grpc_channel_credentials* creds) { 66 if (creds == nullptr) return; 67 if (gpr_unref(&creds->refcount)) { 68 if (creds->vtable->destruct != nullptr) { 69 creds->vtable->destruct(creds); 70 } 71 gpr_free(creds); 72 } 73 } 74 75 void grpc_channel_credentials_release(grpc_channel_credentials* creds) { 76 GRPC_API_TRACE("grpc_channel_credentials_release(creds=%p)", 1, (creds)); 77 grpc_core::ExecCtx exec_ctx; 78 grpc_channel_credentials_unref(creds); 79 } 80 81 grpc_call_credentials* grpc_call_credentials_ref(grpc_call_credentials* creds) { 82 if (creds == nullptr) return nullptr; 83 gpr_ref(&creds->refcount); 84 return creds; 85 } 86 87 void grpc_call_credentials_unref(grpc_call_credentials* creds) { 88 if (creds == nullptr) return; 89 if (gpr_unref(&creds->refcount)) { 90 if (creds->vtable->destruct != nullptr) { 91 creds->vtable->destruct(creds); 92 } 93 gpr_free(creds); 94 } 95 } 96 97 void grpc_call_credentials_release(grpc_call_credentials* creds) { 98 GRPC_API_TRACE("grpc_call_credentials_release(creds=%p)", 1, (creds)); 99 grpc_core::ExecCtx exec_ctx; 100 grpc_call_credentials_unref(creds); 101 } 102 103 bool grpc_call_credentials_get_request_metadata( 104 grpc_call_credentials* creds, grpc_polling_entity* pollent, 105 grpc_auth_metadata_context context, grpc_credentials_mdelem_array* md_array, 106 grpc_closure* on_request_metadata, grpc_error** error) { 107 if (creds == nullptr || creds->vtable->get_request_metadata == nullptr) { 108 return true; 109 } 110 return creds->vtable->get_request_metadata(creds, pollent, context, md_array, 111 on_request_metadata, error); 112 } 113 114 void grpc_call_credentials_cancel_get_request_metadata( 115 grpc_call_credentials* creds, grpc_credentials_mdelem_array* md_array, 116 grpc_error* error) { 117 if (creds == nullptr || 118 creds->vtable->cancel_get_request_metadata == nullptr) { 119 return; 120 } 121 creds->vtable->cancel_get_request_metadata(creds, md_array, error); 122 } 123 124 grpc_security_status grpc_channel_credentials_create_security_connector( 125 grpc_channel_credentials* channel_creds, const char* target, 126 const grpc_channel_args* args, grpc_channel_security_connector** sc, 127 grpc_channel_args** new_args) { 128 *new_args = nullptr; 129 if (channel_creds == nullptr) { 130 return GRPC_SECURITY_ERROR; 131 } 132 GPR_ASSERT(channel_creds->vtable->create_security_connector != nullptr); 133 return channel_creds->vtable->create_security_connector( 134 channel_creds, nullptr, target, args, sc, new_args); 135 } 136 137 grpc_channel_credentials* 138 grpc_channel_credentials_duplicate_without_call_credentials( 139 grpc_channel_credentials* channel_creds) { 140 if (channel_creds != nullptr && channel_creds->vtable != nullptr && 141 channel_creds->vtable->duplicate_without_call_credentials != nullptr) { 142 return channel_creds->vtable->duplicate_without_call_credentials( 143 channel_creds); 144 } else { 145 return grpc_channel_credentials_ref(channel_creds); 146 } 147 } 148 149 static void credentials_pointer_arg_destroy(void* p) { 150 grpc_channel_credentials_unref(static_cast<grpc_channel_credentials*>(p)); 151 } 152 153 static void* credentials_pointer_arg_copy(void* p) { 154 return grpc_channel_credentials_ref( 155 static_cast<grpc_channel_credentials*>(p)); 156 } 157 158 static int credentials_pointer_cmp(void* a, void* b) { return GPR_ICMP(a, b); } 159 160 static const grpc_arg_pointer_vtable credentials_pointer_vtable = { 161 credentials_pointer_arg_copy, credentials_pointer_arg_destroy, 162 credentials_pointer_cmp}; 163 164 grpc_arg grpc_channel_credentials_to_arg( 165 grpc_channel_credentials* credentials) { 166 return grpc_channel_arg_pointer_create((char*)GRPC_ARG_CHANNEL_CREDENTIALS, 167 credentials, 168 &credentials_pointer_vtable); 169 } 170 171 grpc_channel_credentials* grpc_channel_credentials_from_arg( 172 const grpc_arg* arg) { 173 if (strcmp(arg->key, GRPC_ARG_CHANNEL_CREDENTIALS)) return nullptr; 174 if (arg->type != GRPC_ARG_POINTER) { 175 gpr_log(GPR_ERROR, "Invalid type %d for arg %s", arg->type, 176 GRPC_ARG_CHANNEL_CREDENTIALS); 177 return nullptr; 178 } 179 return static_cast<grpc_channel_credentials*>(arg->value.pointer.p); 180 } 181 182 grpc_channel_credentials* grpc_channel_credentials_find_in_args( 183 const grpc_channel_args* args) { 184 size_t i; 185 if (args == nullptr) return nullptr; 186 for (i = 0; i < args->num_args; i++) { 187 grpc_channel_credentials* credentials = 188 grpc_channel_credentials_from_arg(&args->args[i]); 189 if (credentials != nullptr) return credentials; 190 } 191 return nullptr; 192 } 193 194 grpc_server_credentials* grpc_server_credentials_ref( 195 grpc_server_credentials* creds) { 196 if (creds == nullptr) return nullptr; 197 gpr_ref(&creds->refcount); 198 return creds; 199 } 200 201 void grpc_server_credentials_unref(grpc_server_credentials* creds) { 202 if (creds == nullptr) return; 203 if (gpr_unref(&creds->refcount)) { 204 if (creds->vtable->destruct != nullptr) { 205 creds->vtable->destruct(creds); 206 } 207 if (creds->processor.destroy != nullptr && 208 creds->processor.state != nullptr) { 209 creds->processor.destroy(creds->processor.state); 210 } 211 gpr_free(creds); 212 } 213 } 214 215 void grpc_server_credentials_release(grpc_server_credentials* creds) { 216 GRPC_API_TRACE("grpc_server_credentials_release(creds=%p)", 1, (creds)); 217 grpc_core::ExecCtx exec_ctx; 218 grpc_server_credentials_unref(creds); 219 } 220 221 grpc_security_status grpc_server_credentials_create_security_connector( 222 grpc_server_credentials* creds, grpc_server_security_connector** sc) { 223 if (creds == nullptr || creds->vtable->create_security_connector == nullptr) { 224 gpr_log(GPR_ERROR, "Server credentials cannot create security context."); 225 return GRPC_SECURITY_ERROR; 226 } 227 return creds->vtable->create_security_connector(creds, sc); 228 } 229 230 void grpc_server_credentials_set_auth_metadata_processor( 231 grpc_server_credentials* creds, grpc_auth_metadata_processor processor) { 232 GRPC_API_TRACE( 233 "grpc_server_credentials_set_auth_metadata_processor(" 234 "creds=%p, " 235 "processor=grpc_auth_metadata_processor { process: %p, state: %p })", 236 3, (creds, (void*)(intptr_t)processor.process, processor.state)); 237 if (creds == nullptr) return; 238 if (creds->processor.destroy != nullptr && 239 creds->processor.state != nullptr) { 240 creds->processor.destroy(creds->processor.state); 241 } 242 creds->processor = processor; 243 } 244 245 static void server_credentials_pointer_arg_destroy(void* p) { 246 grpc_server_credentials_unref(static_cast<grpc_server_credentials*>(p)); 247 } 248 249 static void* server_credentials_pointer_arg_copy(void* p) { 250 return grpc_server_credentials_ref(static_cast<grpc_server_credentials*>(p)); 251 } 252 253 static int server_credentials_pointer_cmp(void* a, void* b) { 254 return GPR_ICMP(a, b); 255 } 256 257 static const grpc_arg_pointer_vtable cred_ptr_vtable = { 258 server_credentials_pointer_arg_copy, server_credentials_pointer_arg_destroy, 259 server_credentials_pointer_cmp}; 260 261 grpc_arg grpc_server_credentials_to_arg(grpc_server_credentials* p) { 262 return grpc_channel_arg_pointer_create((char*)GRPC_SERVER_CREDENTIALS_ARG, p, 263 &cred_ptr_vtable); 264 } 265 266 grpc_server_credentials* grpc_server_credentials_from_arg(const grpc_arg* arg) { 267 if (strcmp(arg->key, GRPC_SERVER_CREDENTIALS_ARG) != 0) return nullptr; 268 if (arg->type != GRPC_ARG_POINTER) { 269 gpr_log(GPR_ERROR, "Invalid type %d for arg %s", arg->type, 270 GRPC_SERVER_CREDENTIALS_ARG); 271 return nullptr; 272 } 273 return static_cast<grpc_server_credentials*>(arg->value.pointer.p); 274 } 275 276 grpc_server_credentials* grpc_find_server_credentials_in_args( 277 const grpc_channel_args* args) { 278 size_t i; 279 if (args == nullptr) return nullptr; 280 for (i = 0; i < args->num_args; i++) { 281 grpc_server_credentials* p = 282 grpc_server_credentials_from_arg(&args->args[i]); 283 if (p != nullptr) return p; 284 } 285 return nullptr; 286 } 287