Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(296)

Side by Side Diff: third_party/grpc/src/core/security/security_context.c

Issue 1932353002: Initial checkin of gRPC to third_party/ Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 *
3 * Copyright 2015-2016, Google Inc.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following disclaimer
14 * in the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name of Google Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33
34 #include <string.h>
35
36 #include "src/core/security/security_context.h"
37 #include "src/core/surface/api_trace.h"
38 #include "src/core/surface/call.h"
39 #include "src/core/support/string.h"
40
41 #include <grpc/grpc_security.h>
42 #include <grpc/support/alloc.h>
43 #include <grpc/support/log.h>
44 #include <grpc/support/string_util.h>
45
46 /* --- grpc_call --- */
47
48 grpc_call_error grpc_call_set_credentials(grpc_call *call,
49 grpc_call_credentials *creds) {
50 grpc_client_security_context *ctx = NULL;
51 GRPC_API_TRACE("grpc_call_set_credentials(call=%p, creds=%p)", 2,
52 (call, creds));
53 if (!grpc_call_is_client(call)) {
54 gpr_log(GPR_ERROR, "Method is client-side only.");
55 return GRPC_CALL_ERROR_NOT_ON_SERVER;
56 }
57 ctx = (grpc_client_security_context *)grpc_call_context_get(
58 call, GRPC_CONTEXT_SECURITY);
59 if (ctx == NULL) {
60 ctx = grpc_client_security_context_create();
61 ctx->creds = grpc_call_credentials_ref(creds);
62 grpc_call_context_set(call, GRPC_CONTEXT_SECURITY, ctx,
63 grpc_client_security_context_destroy);
64 } else {
65 grpc_call_credentials_unref(ctx->creds);
66 ctx->creds = grpc_call_credentials_ref(creds);
67 }
68 return GRPC_CALL_OK;
69 }
70
71 grpc_auth_context *grpc_call_auth_context(grpc_call *call) {
72 void *sec_ctx = grpc_call_context_get(call, GRPC_CONTEXT_SECURITY);
73 GRPC_API_TRACE("grpc_call_auth_context(call=%p)", 1, (call));
74 if (sec_ctx == NULL) return NULL;
75 return grpc_call_is_client(call)
76 ? GRPC_AUTH_CONTEXT_REF(
77 ((grpc_client_security_context *)sec_ctx)->auth_context,
78 "grpc_call_auth_context client")
79 : GRPC_AUTH_CONTEXT_REF(
80 ((grpc_server_security_context *)sec_ctx)->auth_context,
81 "grpc_call_auth_context server");
82 }
83
84 void grpc_auth_context_release(grpc_auth_context *context) {
85 GRPC_API_TRACE("grpc_auth_context_release(context=%p)", 1, (context));
86 GRPC_AUTH_CONTEXT_UNREF(context, "grpc_auth_context_unref");
87 }
88
89 /* --- grpc_client_security_context --- */
90
91 grpc_client_security_context *grpc_client_security_context_create(void) {
92 grpc_client_security_context *ctx =
93 gpr_malloc(sizeof(grpc_client_security_context));
94 memset(ctx, 0, sizeof(grpc_client_security_context));
95 return ctx;
96 }
97
98 void grpc_client_security_context_destroy(void *ctx) {
99 grpc_client_security_context *c = (grpc_client_security_context *)ctx;
100 grpc_call_credentials_unref(c->creds);
101 GRPC_AUTH_CONTEXT_UNREF(c->auth_context, "client_security_context");
102 gpr_free(ctx);
103 }
104
105 /* --- grpc_server_security_context --- */
106
107 grpc_server_security_context *grpc_server_security_context_create(void) {
108 grpc_server_security_context *ctx =
109 gpr_malloc(sizeof(grpc_server_security_context));
110 memset(ctx, 0, sizeof(grpc_server_security_context));
111 return ctx;
112 }
113
114 void grpc_server_security_context_destroy(void *ctx) {
115 grpc_server_security_context *c = (grpc_server_security_context *)ctx;
116 GRPC_AUTH_CONTEXT_UNREF(c->auth_context, "server_security_context");
117 gpr_free(ctx);
118 }
119
120 /* --- grpc_auth_context --- */
121
122 static grpc_auth_property_iterator empty_iterator = {NULL, 0, NULL};
123
124 grpc_auth_context *grpc_auth_context_create(grpc_auth_context *chained) {
125 grpc_auth_context *ctx = gpr_malloc(sizeof(grpc_auth_context));
126 memset(ctx, 0, sizeof(grpc_auth_context));
127 gpr_ref_init(&ctx->refcount, 1);
128 if (chained != NULL) {
129 ctx->chained = GRPC_AUTH_CONTEXT_REF(chained, "chained");
130 ctx->peer_identity_property_name =
131 ctx->chained->peer_identity_property_name;
132 }
133 return ctx;
134 }
135
136 #ifdef GRPC_AUTH_CONTEXT_REFCOUNT_DEBUG
137 grpc_auth_context *grpc_auth_context_ref(grpc_auth_context *ctx,
138 const char *file, int line,
139 const char *reason) {
140 if (ctx == NULL) return NULL;
141 gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
142 "AUTH_CONTEXT:%p ref %d -> %d %s", ctx, (int)ctx->refcount.count,
143 (int)ctx->refcount.count + 1, reason);
144 #else
145 grpc_auth_context *grpc_auth_context_ref(grpc_auth_context *ctx) {
146 if (ctx == NULL) return NULL;
147 #endif
148 gpr_ref(&ctx->refcount);
149 return ctx;
150 }
151
152 #ifdef GRPC_AUTH_CONTEXT_REFCOUNT_DEBUG
153 void grpc_auth_context_unref(grpc_auth_context *ctx, const char *file, int line,
154 const char *reason) {
155 if (ctx == NULL) return;
156 gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
157 "AUTH_CONTEXT:%p unref %d -> %d %s", ctx, (int)ctx->refcount.count,
158 (int)ctx->refcount.count - 1, reason);
159 #else
160 void grpc_auth_context_unref(grpc_auth_context *ctx) {
161 if (ctx == NULL) return;
162 #endif
163 if (gpr_unref(&ctx->refcount)) {
164 size_t i;
165 GRPC_AUTH_CONTEXT_UNREF(ctx->chained, "chained");
166 if (ctx->properties.array != NULL) {
167 for (i = 0; i < ctx->properties.count; i++) {
168 grpc_auth_property_reset(&ctx->properties.array[i]);
169 }
170 gpr_free(ctx->properties.array);
171 }
172 gpr_free(ctx);
173 }
174 }
175
176 const char *grpc_auth_context_peer_identity_property_name(
177 const grpc_auth_context *ctx) {
178 GRPC_API_TRACE("grpc_auth_context_peer_identity_property_name(ctx=%p)", 1,
179 (ctx));
180 return ctx->peer_identity_property_name;
181 }
182
183 int grpc_auth_context_set_peer_identity_property_name(grpc_auth_context *ctx,
184 const char *name) {
185 grpc_auth_property_iterator it =
186 grpc_auth_context_find_properties_by_name(ctx, name);
187 const grpc_auth_property *prop = grpc_auth_property_iterator_next(&it);
188 GRPC_API_TRACE(
189 "grpc_auth_context_set_peer_identity_property_name(ctx=%p, name=%s)", 2,
190 (ctx, name));
191 if (prop == NULL) {
192 gpr_log(GPR_ERROR, "Property name %s not found in auth context.",
193 name != NULL ? name : "NULL");
194 return 0;
195 }
196 ctx->peer_identity_property_name = prop->name;
197 return 1;
198 }
199
200 int grpc_auth_context_peer_is_authenticated(const grpc_auth_context *ctx) {
201 GRPC_API_TRACE("grpc_auth_context_peer_is_authenticated(ctx=%p)", 1, (ctx));
202 return ctx->peer_identity_property_name == NULL ? 0 : 1;
203 }
204
205 grpc_auth_property_iterator grpc_auth_context_property_iterator(
206 const grpc_auth_context *ctx) {
207 grpc_auth_property_iterator it = empty_iterator;
208 GRPC_API_TRACE("grpc_auth_context_property_iterator(ctx=%p)", 1, (ctx));
209 if (ctx == NULL) return it;
210 it.ctx = ctx;
211 return it;
212 }
213
214 const grpc_auth_property *grpc_auth_property_iterator_next(
215 grpc_auth_property_iterator *it) {
216 GRPC_API_TRACE("grpc_auth_property_iterator_next(it=%p)", 1, (it));
217 if (it == NULL || it->ctx == NULL) return NULL;
218 while (it->index == it->ctx->properties.count) {
219 if (it->ctx->chained == NULL) return NULL;
220 it->ctx = it->ctx->chained;
221 it->index = 0;
222 }
223 if (it->name == NULL) {
224 return &it->ctx->properties.array[it->index++];
225 } else {
226 while (it->index < it->ctx->properties.count) {
227 const grpc_auth_property *prop = &it->ctx->properties.array[it->index++];
228 GPR_ASSERT(prop->name != NULL);
229 if (strcmp(it->name, prop->name) == 0) {
230 return prop;
231 }
232 }
233 /* We could not find the name, try another round. */
234 return grpc_auth_property_iterator_next(it);
235 }
236 }
237
238 grpc_auth_property_iterator grpc_auth_context_find_properties_by_name(
239 const grpc_auth_context *ctx, const char *name) {
240 grpc_auth_property_iterator it = empty_iterator;
241 GRPC_API_TRACE("grpc_auth_context_find_properties_by_name(ctx=%p, name=%s)",
242 2, (ctx, name));
243 if (ctx == NULL || name == NULL) return empty_iterator;
244 it.ctx = ctx;
245 it.name = name;
246 return it;
247 }
248
249 grpc_auth_property_iterator grpc_auth_context_peer_identity(
250 const grpc_auth_context *ctx) {
251 GRPC_API_TRACE("grpc_auth_context_peer_identity(ctx=%p)", 1, (ctx));
252 if (ctx == NULL) return empty_iterator;
253 return grpc_auth_context_find_properties_by_name(
254 ctx, ctx->peer_identity_property_name);
255 }
256
257 static void ensure_auth_context_capacity(grpc_auth_context *ctx) {
258 if (ctx->properties.count == ctx->properties.capacity) {
259 ctx->properties.capacity =
260 GPR_MAX(ctx->properties.capacity + 8, ctx->properties.capacity * 2);
261 ctx->properties.array =
262 gpr_realloc(ctx->properties.array,
263 ctx->properties.capacity * sizeof(grpc_auth_property));
264 }
265 }
266
267 void grpc_auth_context_add_property(grpc_auth_context *ctx, const char *name,
268 const char *value, size_t value_length) {
269 grpc_auth_property *prop;
270 GRPC_API_TRACE(
271 "grpc_auth_context_add_property(ctx=%p, name=%s, value=%*.*s, "
272 "value_length=%lu)",
273 6, (ctx, name, (int)value_length, (int)value_length, value,
274 (unsigned long)value_length));
275 ensure_auth_context_capacity(ctx);
276 prop = &ctx->properties.array[ctx->properties.count++];
277 prop->name = gpr_strdup(name);
278 prop->value = gpr_malloc(value_length + 1);
279 memcpy(prop->value, value, value_length);
280 prop->value[value_length] = '\0';
281 prop->value_length = value_length;
282 }
283
284 void grpc_auth_context_add_cstring_property(grpc_auth_context *ctx,
285 const char *name,
286 const char *value) {
287 grpc_auth_property *prop;
288 GRPC_API_TRACE(
289 "grpc_auth_context_add_cstring_property(ctx=%p, name=%s, value=%s)", 3,
290 (ctx, name, value));
291 ensure_auth_context_capacity(ctx);
292 prop = &ctx->properties.array[ctx->properties.count++];
293 prop->name = gpr_strdup(name);
294 prop->value = gpr_strdup(value);
295 prop->value_length = strlen(value);
296 }
297
298 void grpc_auth_property_reset(grpc_auth_property *property) {
299 gpr_free(property->name);
300 gpr_free(property->value);
301 memset(property, 0, sizeof(grpc_auth_property));
302 }
303
304 static void auth_context_pointer_arg_destroy(void *p) {
305 GRPC_AUTH_CONTEXT_UNREF(p, "auth_context_pointer_arg");
306 }
307
308 static void *auth_context_pointer_arg_copy(void *p) {
309 return GRPC_AUTH_CONTEXT_REF(p, "auth_context_pointer_arg");
310 }
311
312 static int auth_context_pointer_cmp(void *a, void *b) { return GPR_ICMP(a, b); }
313
314 static const grpc_arg_pointer_vtable auth_context_pointer_vtable = {
315 auth_context_pointer_arg_copy, auth_context_pointer_arg_destroy,
316 auth_context_pointer_cmp};
317
318 grpc_arg grpc_auth_context_to_arg(grpc_auth_context *p) {
319 grpc_arg arg;
320 memset(&arg, 0, sizeof(grpc_arg));
321 arg.type = GRPC_ARG_POINTER;
322 arg.key = GRPC_AUTH_CONTEXT_ARG;
323 arg.value.pointer.p = p;
324 arg.value.pointer.vtable = &auth_context_pointer_vtable;
325 return arg;
326 }
327
328 grpc_auth_context *grpc_auth_context_from_arg(const grpc_arg *arg) {
329 if (strcmp(arg->key, GRPC_AUTH_CONTEXT_ARG) != 0) return NULL;
330 if (arg->type != GRPC_ARG_POINTER) {
331 gpr_log(GPR_ERROR, "Invalid type %d for arg %s", arg->type,
332 GRPC_AUTH_CONTEXT_ARG);
333 return NULL;
334 }
335 return arg->value.pointer.p;
336 }
337
338 grpc_auth_context *grpc_find_auth_context_in_args(
339 const grpc_channel_args *args) {
340 size_t i;
341 if (args == NULL) return NULL;
342 for (i = 0; i < args->num_args; i++) {
343 grpc_auth_context *p = grpc_auth_context_from_arg(&args->args[i]);
344 if (p != NULL) return p;
345 }
346 return NULL;
347 }
OLDNEW
« no previous file with comments | « third_party/grpc/src/core/security/security_context.h ('k') | third_party/grpc/src/core/security/server_auth_filter.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698