Line data Source code
1 : /*
2 : *
3 : * Copyright 2015, 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 "src/core/security/credentials.h"
35 :
36 : #include <string.h>
37 :
38 : #include "src/core/httpcli/httpcli.h"
39 : #include "src/core/security/json_token.h"
40 : #include "src/core/support/env.h"
41 : #include "src/core/support/file.h"
42 : #include "src/core/support/string.h"
43 :
44 : #include "test/core/util/test_config.h"
45 :
46 : #include <grpc/support/alloc.h>
47 : #include <grpc/support/log.h>
48 : #include <grpc/support/string_util.h>
49 : #include <grpc/support/time.h>
50 :
51 : #include <openssl/rsa.h>
52 :
53 : static const char test_google_iam_authorization_token[] = "blahblahblhahb";
54 : static const char test_google_iam_authority_selector[] = "respectmyauthoritah";
55 : static const char test_oauth2_bearer_token[] =
56 : "Bearer blaaslkdjfaslkdfasdsfasf";
57 : static const char test_root_cert[] = "I am the root!";
58 :
59 : /* This JSON key was generated with the GCE console and revoked immediately.
60 : The identifiers have been changed as well.
61 : Maximum size for a string literal is 509 chars in C89, yay! */
62 : static const char test_json_key_str_part1[] =
63 : "{ \"private_key\": \"-----BEGIN PRIVATE KEY-----"
64 : "\\nMIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAOEvJsnoHnyHkXcp\\n7mJE"
65 : "qg"
66 : "WGjiw71NfXByguekSKho65FxaGbsnSM9SMQAqVk7Q2rG+I0OpsT0LrWQtZ\\nyjSeg/"
67 : "rWBQvS4hle4LfijkP3J5BG+"
68 : "IXDMP8RfziNRQsenAXDNPkY4kJCvKux2xdD\\nOnVF6N7dL3nTYZg+"
69 : "uQrNsMTz9UxVAgMBAAECgYEAzbLewe1xe9vy+2GoSsfib+28\\nDZgSE6Bu/"
70 : "zuFoPrRc6qL9p2SsnV7txrunTyJkkOnPLND9ABAXybRTlcVKP/sGgza\\n/"
71 : "8HpCqFYM9V8f34SBWfD4fRFT+n/"
72 : "73cfRUtGXdXpseva2lh8RilIQfPhNZAncenU\\ngqXjDvpkypEusgXAykECQQD+";
73 : static const char test_json_key_str_part2[] =
74 : "53XxNVnxBHsYb+AYEfklR96yVi8HywjVHP34+OQZ\\nCslxoHQM8s+"
75 : "dBnjfScLu22JqkPv04xyxmt0QAKm9+vTdAkEA4ib7YvEAn2jXzcCI\\nEkoy2L/"
76 : "XydR1GCHoacdfdAwiL2npOdnbvi4ZmdYRPY1LSTO058tQHKVXV7NLeCa3\\nAARh2QJBAMKeDA"
77 : "G"
78 : "W303SQv2cZTdbeaLKJbB5drz3eo3j7dDKjrTD9JupixFbzcGw\\n8FZi5c8idxiwC36kbAL6Hz"
79 : "A"
80 : "ZoX+ofI0CQE6KCzPJTtYNqyShgKAZdJ8hwOcvCZtf\\n6z8RJm0+"
81 : "6YBd38lfh5j8mZd7aHFf6I17j5AQY7oPEc47TjJj/"
82 : "5nZ68ECQQDvYuI3\\nLyK5fS8g0SYbmPOL9TlcHDOqwG0mrX9qpg5DC2fniXNSrrZ64GTDKdzZ"
83 : "Y"
84 : "Ap6LI9W\\nIqv4vr6y38N79TTC\\n-----END PRIVATE KEY-----\\n\", ";
85 : static const char test_json_key_str_part3[] =
86 : "\"private_key_id\": \"e6b5137873db8d2ef81e06a47289e6434ec8a165\", "
87 : "\"client_email\": "
88 : "\"777-abaslkan11hlb6nmim3bpspl31ud@developer.gserviceaccount."
89 : "com\", \"client_id\": "
90 : "\"777-abaslkan11hlb6nmim3bpspl31ud.apps.googleusercontent."
91 : "com\", \"type\": \"service_account\" }";
92 :
93 : /* Test refresh token. */
94 : static const char test_refresh_token_str[] =
95 : "{ \"client_id\": \"32555999999.apps.googleusercontent.com\","
96 : " \"client_secret\": \"EmssLNjJy1332hD4KFsecret\","
97 : " \"refresh_token\": \"1/Blahblasj424jladJDSGNf-u4Sua3HDA2ngjd42\","
98 : " \"type\": \"authorized_user\"}";
99 :
100 : static const char valid_oauth2_json_response[] =
101 : "{\"access_token\":\"ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_\","
102 : " \"expires_in\":3599, "
103 : " \"token_type\":\"Bearer\"}";
104 :
105 : static const char test_user_data[] = "user data";
106 :
107 : static const char test_scope[] = "perm1 perm2";
108 :
109 : static const char test_signed_jwt[] =
110 : "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImY0OTRkN2M1YWU2MGRmOTcyNmM4YW"
111 : "U0MDcyZTViYTdmZDkwODg2YzcifQ";
112 :
113 : static const char test_service_url[] = "https://foo.com/foo.v1";
114 : static const char other_test_service_url[] = "https://bar.com/bar.v1";
115 :
116 3 : static char *test_json_key_str(void) {
117 3 : size_t result_len = strlen(test_json_key_str_part1) +
118 : strlen(test_json_key_str_part2) +
119 : strlen(test_json_key_str_part3);
120 3 : char *result = gpr_malloc(result_len + 1);
121 3 : char *current = result;
122 3 : strcpy(result, test_json_key_str_part1);
123 3 : current += strlen(test_json_key_str_part1);
124 3 : strcpy(current, test_json_key_str_part2);
125 3 : current += strlen(test_json_key_str_part2);
126 3 : strcpy(current, test_json_key_str_part3);
127 3 : return result;
128 : }
129 :
130 : typedef struct {
131 : const char *key;
132 : const char *value;
133 : } expected_md;
134 :
135 11 : static grpc_httpcli_response http_response(int status, const char *body) {
136 : grpc_httpcli_response response;
137 11 : memset(&response, 0, sizeof(grpc_httpcli_response));
138 11 : response.status = status;
139 11 : response.body = (char *)body;
140 11 : response.body_length = strlen(body);
141 11 : return response;
142 : }
143 :
144 1 : static void test_empty_md_store(void) {
145 1 : grpc_credentials_md_store *store = grpc_credentials_md_store_create(0);
146 1 : GPR_ASSERT(store->num_entries == 0);
147 1 : GPR_ASSERT(store->allocated == 0);
148 1 : grpc_credentials_md_store_unref(store);
149 1 : }
150 :
151 1 : static void test_ref_unref_empty_md_store(void) {
152 1 : grpc_credentials_md_store *store = grpc_credentials_md_store_create(0);
153 1 : grpc_credentials_md_store_ref(store);
154 1 : grpc_credentials_md_store_ref(store);
155 1 : GPR_ASSERT(store->num_entries == 0);
156 1 : GPR_ASSERT(store->allocated == 0);
157 1 : grpc_credentials_md_store_unref(store);
158 1 : grpc_credentials_md_store_unref(store);
159 1 : grpc_credentials_md_store_unref(store);
160 1 : }
161 :
162 1 : static void test_add_to_empty_md_store(void) {
163 1 : grpc_credentials_md_store *store = grpc_credentials_md_store_create(0);
164 1 : const char *key_str = "hello";
165 1 : const char *value_str = "there blah blah blah blah blah blah blah";
166 1 : gpr_slice key = gpr_slice_from_copied_string(key_str);
167 1 : gpr_slice value = gpr_slice_from_copied_string(value_str);
168 1 : grpc_credentials_md_store_add(store, key, value);
169 1 : GPR_ASSERT(store->num_entries == 1);
170 1 : GPR_ASSERT(gpr_slice_cmp(key, store->entries[0].key) == 0);
171 1 : GPR_ASSERT(gpr_slice_cmp(value, store->entries[0].value) == 0);
172 1 : gpr_slice_unref(key);
173 1 : gpr_slice_unref(value);
174 1 : grpc_credentials_md_store_unref(store);
175 1 : }
176 :
177 1 : static void test_add_cstrings_to_empty_md_store(void) {
178 1 : grpc_credentials_md_store *store = grpc_credentials_md_store_create(0);
179 1 : const char *key_str = "hello";
180 1 : const char *value_str = "there blah blah blah blah blah blah blah";
181 1 : grpc_credentials_md_store_add_cstrings(store, key_str, value_str);
182 1 : GPR_ASSERT(store->num_entries == 1);
183 1 : GPR_ASSERT(gpr_slice_str_cmp(store->entries[0].key, key_str) == 0);
184 1 : GPR_ASSERT(gpr_slice_str_cmp(store->entries[0].value, value_str) == 0);
185 1 : grpc_credentials_md_store_unref(store);
186 1 : }
187 :
188 1 : static void test_empty_preallocated_md_store(void) {
189 1 : grpc_credentials_md_store *store = grpc_credentials_md_store_create(4);
190 1 : GPR_ASSERT(store->num_entries == 0);
191 1 : GPR_ASSERT(store->allocated == 4);
192 1 : GPR_ASSERT(store->entries != NULL);
193 1 : grpc_credentials_md_store_unref(store);
194 1 : }
195 :
196 1 : static void test_add_abunch_to_md_store(void) {
197 1 : grpc_credentials_md_store *store = grpc_credentials_md_store_create(4);
198 1 : size_t num_entries = 1000;
199 1 : const char *key_str = "hello";
200 1 : const char *value_str = "there blah blah blah blah blah blah blah";
201 : size_t i;
202 1001 : for (i = 0; i < num_entries; i++) {
203 1000 : grpc_credentials_md_store_add_cstrings(store, key_str, value_str);
204 : }
205 1001 : for (i = 0; i < num_entries; i++) {
206 1000 : GPR_ASSERT(gpr_slice_str_cmp(store->entries[i].key, key_str) == 0);
207 1000 : GPR_ASSERT(gpr_slice_str_cmp(store->entries[i].value, value_str) == 0);
208 : }
209 1 : grpc_credentials_md_store_unref(store);
210 1 : }
211 :
212 1 : static void test_oauth2_token_fetcher_creds_parsing_ok(void) {
213 1 : grpc_credentials_md_store *token_md = NULL;
214 : gpr_timespec token_lifetime;
215 1 : grpc_httpcli_response response =
216 : http_response(200, valid_oauth2_json_response);
217 1 : GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
218 : &response, &token_md, &token_lifetime) == GRPC_CREDENTIALS_OK);
219 1 : GPR_ASSERT(token_lifetime.tv_sec == 3599);
220 1 : GPR_ASSERT(token_lifetime.tv_nsec == 0);
221 1 : GPR_ASSERT(token_md->num_entries == 1);
222 1 : GPR_ASSERT(gpr_slice_str_cmp(token_md->entries[0].key, "Authorization") == 0);
223 1 : GPR_ASSERT(gpr_slice_str_cmp(token_md->entries[0].value,
224 : "Bearer ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_") ==
225 : 0);
226 1 : grpc_credentials_md_store_unref(token_md);
227 1 : }
228 :
229 1 : static void test_oauth2_token_fetcher_creds_parsing_bad_http_status(void) {
230 1 : grpc_credentials_md_store *token_md = NULL;
231 : gpr_timespec token_lifetime;
232 1 : grpc_httpcli_response response =
233 : http_response(401, valid_oauth2_json_response);
234 1 : GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
235 : &response, &token_md, &token_lifetime) ==
236 : GRPC_CREDENTIALS_ERROR);
237 1 : }
238 :
239 1 : static void test_oauth2_token_fetcher_creds_parsing_empty_http_body(void) {
240 1 : grpc_credentials_md_store *token_md = NULL;
241 : gpr_timespec token_lifetime;
242 1 : grpc_httpcli_response response = http_response(200, "");
243 1 : GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
244 : &response, &token_md, &token_lifetime) ==
245 : GRPC_CREDENTIALS_ERROR);
246 1 : }
247 :
248 1 : static void test_oauth2_token_fetcher_creds_parsing_invalid_json(void) {
249 1 : grpc_credentials_md_store *token_md = NULL;
250 : gpr_timespec token_lifetime;
251 1 : grpc_httpcli_response response =
252 : http_response(200,
253 : "{\"access_token\":\"ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_\","
254 : " \"expires_in\":3599, "
255 : " \"token_type\":\"Bearer\"");
256 1 : GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
257 : &response, &token_md, &token_lifetime) ==
258 : GRPC_CREDENTIALS_ERROR);
259 1 : }
260 :
261 1 : static void test_oauth2_token_fetcher_creds_parsing_missing_token(void) {
262 1 : grpc_credentials_md_store *token_md = NULL;
263 : gpr_timespec token_lifetime;
264 1 : grpc_httpcli_response response = http_response(200,
265 : "{"
266 : " \"expires_in\":3599, "
267 : " \"token_type\":\"Bearer\"}");
268 1 : GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
269 : &response, &token_md, &token_lifetime) ==
270 : GRPC_CREDENTIALS_ERROR);
271 1 : }
272 :
273 1 : static void test_oauth2_token_fetcher_creds_parsing_missing_token_type(void) {
274 1 : grpc_credentials_md_store *token_md = NULL;
275 : gpr_timespec token_lifetime;
276 1 : grpc_httpcli_response response =
277 : http_response(200,
278 : "{\"access_token\":\"ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_\","
279 : " \"expires_in\":3599, "
280 : "}");
281 1 : GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
282 : &response, &token_md, &token_lifetime) ==
283 : GRPC_CREDENTIALS_ERROR);
284 1 : }
285 :
286 1 : static void test_oauth2_token_fetcher_creds_parsing_missing_token_lifetime(
287 : void) {
288 1 : grpc_credentials_md_store *token_md = NULL;
289 : gpr_timespec token_lifetime;
290 1 : grpc_httpcli_response response =
291 : http_response(200,
292 : "{\"access_token\":\"ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_\","
293 : " \"token_type\":\"Bearer\"}");
294 1 : GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response(
295 : &response, &token_md, &token_lifetime) ==
296 : GRPC_CREDENTIALS_ERROR);
297 1 : }
298 :
299 4 : static void check_metadata(expected_md *expected, grpc_credentials_md *md_elems,
300 : size_t num_md) {
301 : size_t i;
302 11 : for (i = 0; i < num_md; i++) {
303 : size_t j;
304 11 : for (j = 0; j < num_md; j++) {
305 11 : if (0 == gpr_slice_str_cmp(md_elems[j].key, expected[i].key)) {
306 7 : GPR_ASSERT(gpr_slice_str_cmp(md_elems[j].value, expected[i].value) ==
307 : 0);
308 7 : break;
309 : }
310 : }
311 7 : if (j == num_md) {
312 0 : gpr_log(GPR_ERROR, "key %s not found", expected[i].key);
313 0 : GPR_ASSERT(0);
314 : }
315 : }
316 4 : }
317 :
318 1 : static void check_google_iam_metadata(grpc_exec_ctx *exec_ctx, void *user_data,
319 : grpc_credentials_md *md_elems,
320 : size_t num_md,
321 : grpc_credentials_status status) {
322 1 : grpc_credentials *c = (grpc_credentials *)user_data;
323 1 : expected_md emd[] = {{GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY,
324 : test_google_iam_authorization_token},
325 : {GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY,
326 : test_google_iam_authority_selector}};
327 1 : GPR_ASSERT(status == GRPC_CREDENTIALS_OK);
328 1 : GPR_ASSERT(num_md == 2);
329 1 : check_metadata(emd, md_elems, num_md);
330 1 : grpc_credentials_unref(c);
331 1 : }
332 :
333 1 : static void test_google_iam_creds(void) {
334 1 : grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
335 1 : grpc_credentials *creds = grpc_google_iam_credentials_create(
336 : test_google_iam_authorization_token, test_google_iam_authority_selector,
337 : NULL);
338 1 : GPR_ASSERT(grpc_credentials_has_request_metadata(creds));
339 1 : GPR_ASSERT(grpc_credentials_has_request_metadata_only(creds));
340 1 : grpc_credentials_get_request_metadata(&exec_ctx, creds, NULL,
341 : test_service_url,
342 : check_google_iam_metadata, creds);
343 1 : grpc_exec_ctx_finish(&exec_ctx);
344 1 : }
345 :
346 1 : static void check_access_token_metadata(grpc_exec_ctx *exec_ctx,
347 : void *user_data,
348 : grpc_credentials_md *md_elems,
349 : size_t num_md,
350 : grpc_credentials_status status) {
351 1 : grpc_credentials *c = (grpc_credentials *)user_data;
352 1 : expected_md emd[] = {{GRPC_AUTHORIZATION_METADATA_KEY, "Bearer blah"}};
353 1 : GPR_ASSERT(status == GRPC_CREDENTIALS_OK);
354 1 : GPR_ASSERT(num_md == 1);
355 1 : check_metadata(emd, md_elems, num_md);
356 1 : grpc_credentials_unref(c);
357 1 : }
358 :
359 1 : static void test_access_token_creds(void) {
360 1 : grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
361 1 : grpc_credentials *creds = grpc_access_token_credentials_create("blah", NULL);
362 1 : GPR_ASSERT(grpc_credentials_has_request_metadata(creds));
363 1 : GPR_ASSERT(grpc_credentials_has_request_metadata_only(creds));
364 1 : GPR_ASSERT(strcmp(creds->type, GRPC_CREDENTIALS_TYPE_OAUTH2) == 0);
365 1 : grpc_credentials_get_request_metadata(&exec_ctx, creds, NULL,
366 : test_service_url,
367 : check_access_token_metadata, creds);
368 1 : grpc_exec_ctx_finish(&exec_ctx);
369 1 : }
370 :
371 1 : static void check_ssl_oauth2_composite_metadata(
372 : grpc_exec_ctx *exec_ctx, void *user_data, grpc_credentials_md *md_elems,
373 : size_t num_md, grpc_credentials_status status) {
374 1 : grpc_credentials *c = (grpc_credentials *)user_data;
375 1 : expected_md emd[] = {
376 : {GRPC_AUTHORIZATION_METADATA_KEY, test_oauth2_bearer_token}};
377 1 : GPR_ASSERT(status == GRPC_CREDENTIALS_OK);
378 1 : GPR_ASSERT(num_md == 1);
379 1 : check_metadata(emd, md_elems, num_md);
380 1 : grpc_credentials_unref(c);
381 1 : }
382 :
383 1 : static void test_ssl_oauth2_composite_creds(void) {
384 1 : grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
385 1 : grpc_credentials *ssl_creds =
386 : grpc_ssl_credentials_create(test_root_cert, NULL, NULL);
387 : const grpc_credentials_array *creds_array;
388 1 : grpc_credentials *oauth2_creds = grpc_md_only_test_credentials_create(
389 : "Authorization", test_oauth2_bearer_token, 0);
390 1 : grpc_credentials *composite_creds =
391 : grpc_composite_credentials_create(ssl_creds, oauth2_creds, NULL);
392 1 : grpc_credentials_unref(ssl_creds);
393 1 : grpc_credentials_unref(oauth2_creds);
394 1 : GPR_ASSERT(strcmp(composite_creds->type, GRPC_CREDENTIALS_TYPE_COMPOSITE) ==
395 : 0);
396 1 : GPR_ASSERT(grpc_credentials_has_request_metadata(composite_creds));
397 1 : GPR_ASSERT(!grpc_credentials_has_request_metadata_only(composite_creds));
398 1 : creds_array = grpc_composite_credentials_get_credentials(composite_creds);
399 1 : GPR_ASSERT(creds_array->num_creds == 2);
400 1 : GPR_ASSERT(strcmp(creds_array->creds_array[0]->type,
401 : GRPC_CREDENTIALS_TYPE_SSL) == 0);
402 1 : GPR_ASSERT(strcmp(creds_array->creds_array[1]->type,
403 : GRPC_CREDENTIALS_TYPE_OAUTH2) == 0);
404 1 : grpc_credentials_get_request_metadata(
405 : &exec_ctx, composite_creds, NULL, test_service_url,
406 : check_ssl_oauth2_composite_metadata, composite_creds);
407 1 : grpc_exec_ctx_finish(&exec_ctx);
408 1 : }
409 :
410 0 : void test_ssl_fake_transport_security_composite_creds_failure(void) {
411 0 : grpc_credentials *ssl_creds = grpc_ssl_credentials_create(NULL, NULL, NULL);
412 0 : grpc_credentials *fake_transport_security_creds =
413 : grpc_fake_transport_security_credentials_create();
414 :
415 : /* 2 connector credentials: should not work. */
416 0 : GPR_ASSERT(grpc_composite_credentials_create(
417 : ssl_creds, fake_transport_security_creds, NULL) == NULL);
418 0 : grpc_credentials_unref(ssl_creds);
419 0 : grpc_credentials_unref(fake_transport_security_creds);
420 0 : }
421 :
422 1 : static void check_ssl_oauth2_google_iam_composite_metadata(
423 : grpc_exec_ctx *exec_ctx, void *user_data, grpc_credentials_md *md_elems,
424 : size_t num_md, grpc_credentials_status status) {
425 1 : grpc_credentials *c = (grpc_credentials *)user_data;
426 1 : expected_md emd[] = {
427 : {GRPC_AUTHORIZATION_METADATA_KEY, test_oauth2_bearer_token},
428 : {GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY,
429 : test_google_iam_authorization_token},
430 : {GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY,
431 : test_google_iam_authority_selector}};
432 1 : GPR_ASSERT(status == GRPC_CREDENTIALS_OK);
433 1 : GPR_ASSERT(num_md == 3);
434 1 : check_metadata(emd, md_elems, num_md);
435 1 : grpc_credentials_unref(c);
436 1 : }
437 :
438 1 : static void test_ssl_oauth2_google_iam_composite_creds(void) {
439 1 : grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
440 1 : grpc_credentials *ssl_creds =
441 : grpc_ssl_credentials_create(test_root_cert, NULL, NULL);
442 : const grpc_credentials_array *creds_array;
443 1 : grpc_credentials *oauth2_creds = grpc_md_only_test_credentials_create(
444 : "Authorization", test_oauth2_bearer_token, 0);
445 1 : grpc_credentials *aux_creds =
446 : grpc_composite_credentials_create(ssl_creds, oauth2_creds, NULL);
447 1 : grpc_credentials *google_iam_creds = grpc_google_iam_credentials_create(
448 : test_google_iam_authorization_token, test_google_iam_authority_selector,
449 : NULL);
450 1 : grpc_credentials *composite_creds =
451 : grpc_composite_credentials_create(aux_creds, google_iam_creds, NULL);
452 1 : grpc_credentials_unref(ssl_creds);
453 1 : grpc_credentials_unref(oauth2_creds);
454 1 : grpc_credentials_unref(aux_creds);
455 1 : grpc_credentials_unref(google_iam_creds);
456 1 : GPR_ASSERT(strcmp(composite_creds->type, GRPC_CREDENTIALS_TYPE_COMPOSITE) ==
457 : 0);
458 1 : GPR_ASSERT(grpc_credentials_has_request_metadata(composite_creds));
459 1 : GPR_ASSERT(!grpc_credentials_has_request_metadata_only(composite_creds));
460 1 : creds_array = grpc_composite_credentials_get_credentials(composite_creds);
461 1 : GPR_ASSERT(creds_array->num_creds == 3);
462 1 : GPR_ASSERT(strcmp(creds_array->creds_array[0]->type,
463 : GRPC_CREDENTIALS_TYPE_SSL) == 0);
464 1 : GPR_ASSERT(strcmp(creds_array->creds_array[1]->type,
465 : GRPC_CREDENTIALS_TYPE_OAUTH2) == 0);
466 1 : GPR_ASSERT(strcmp(creds_array->creds_array[2]->type,
467 : GRPC_CREDENTIALS_TYPE_IAM) == 0);
468 1 : grpc_credentials_get_request_metadata(
469 : &exec_ctx, composite_creds, NULL, test_service_url,
470 : check_ssl_oauth2_google_iam_composite_metadata, composite_creds);
471 1 : grpc_exec_ctx_finish(&exec_ctx);
472 1 : }
473 :
474 4 : static void on_oauth2_creds_get_metadata_success(
475 : grpc_exec_ctx *exec_ctx, void *user_data, grpc_credentials_md *md_elems,
476 : size_t num_md, grpc_credentials_status status) {
477 4 : GPR_ASSERT(status == GRPC_CREDENTIALS_OK);
478 4 : GPR_ASSERT(num_md == 1);
479 4 : GPR_ASSERT(gpr_slice_str_cmp(md_elems[0].key, "Authorization") == 0);
480 4 : GPR_ASSERT(gpr_slice_str_cmp(md_elems[0].value,
481 : "Bearer ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_") ==
482 : 0);
483 4 : GPR_ASSERT(user_data != NULL);
484 4 : GPR_ASSERT(strcmp((const char *)user_data, test_user_data) == 0);
485 4 : }
486 :
487 2 : static void on_oauth2_creds_get_metadata_failure(
488 : grpc_exec_ctx *exec_ctx, void *user_data, grpc_credentials_md *md_elems,
489 : size_t num_md, grpc_credentials_status status) {
490 2 : GPR_ASSERT(status == GRPC_CREDENTIALS_ERROR);
491 2 : GPR_ASSERT(num_md == 0);
492 2 : GPR_ASSERT(user_data != NULL);
493 2 : GPR_ASSERT(strcmp((const char *)user_data, test_user_data) == 0);
494 2 : }
495 :
496 2 : static void validate_compute_engine_http_request(
497 : const grpc_httpcli_request *request) {
498 2 : GPR_ASSERT(request->handshaker != &grpc_httpcli_ssl);
499 2 : GPR_ASSERT(strcmp(request->host, "metadata") == 0);
500 2 : GPR_ASSERT(
501 : strcmp(request->path,
502 : "/computeMetadata/v1/instance/service-accounts/default/token") ==
503 : 0);
504 2 : GPR_ASSERT(request->hdr_count == 1);
505 2 : GPR_ASSERT(strcmp(request->hdrs[0].key, "Metadata-Flavor") == 0);
506 2 : GPR_ASSERT(strcmp(request->hdrs[0].value, "Google") == 0);
507 2 : }
508 :
509 1 : static int compute_engine_httpcli_get_success_override(
510 : grpc_exec_ctx *exec_ctx, const grpc_httpcli_request *request,
511 : gpr_timespec deadline, grpc_httpcli_response_cb on_response,
512 : void *user_data) {
513 1 : grpc_httpcli_response response =
514 : http_response(200, valid_oauth2_json_response);
515 1 : validate_compute_engine_http_request(request);
516 1 : on_response(exec_ctx, user_data, &response);
517 1 : return 1;
518 : }
519 :
520 1 : static int compute_engine_httpcli_get_failure_override(
521 : grpc_exec_ctx *exec_ctx, const grpc_httpcli_request *request,
522 : gpr_timespec deadline, grpc_httpcli_response_cb on_response,
523 : void *user_data) {
524 1 : grpc_httpcli_response response = http_response(403, "Not Authorized.");
525 1 : validate_compute_engine_http_request(request);
526 1 : on_response(exec_ctx, user_data, &response);
527 1 : return 1;
528 : }
529 :
530 0 : static int httpcli_post_should_not_be_called(
531 : grpc_exec_ctx *exec_ctx, const grpc_httpcli_request *request,
532 : const char *body_bytes, size_t body_size, gpr_timespec deadline,
533 : grpc_httpcli_response_cb on_response, void *user_data) {
534 0 : GPR_ASSERT("HTTP POST should not be called" == NULL);
535 : return 1;
536 : }
537 :
538 0 : static int httpcli_get_should_not_be_called(
539 : grpc_exec_ctx *exec_ctx, const grpc_httpcli_request *request,
540 : gpr_timespec deadline, grpc_httpcli_response_cb on_response,
541 : void *user_data) {
542 0 : GPR_ASSERT("HTTP GET should not be called" == NULL);
543 : return 1;
544 : }
545 :
546 1 : static void test_compute_engine_creds_success(void) {
547 1 : grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
548 1 : grpc_credentials *compute_engine_creds =
549 : grpc_google_compute_engine_credentials_create(NULL);
550 1 : GPR_ASSERT(grpc_credentials_has_request_metadata(compute_engine_creds));
551 1 : GPR_ASSERT(grpc_credentials_has_request_metadata_only(compute_engine_creds));
552 :
553 : /* First request: http get should be called. */
554 1 : grpc_httpcli_set_override(compute_engine_httpcli_get_success_override,
555 : httpcli_post_should_not_be_called);
556 1 : grpc_credentials_get_request_metadata(
557 : &exec_ctx, compute_engine_creds, NULL, test_service_url,
558 : on_oauth2_creds_get_metadata_success, (void *)test_user_data);
559 1 : grpc_exec_ctx_flush(&exec_ctx);
560 :
561 : /* Second request: the cached token should be served directly. */
562 1 : grpc_httpcli_set_override(httpcli_get_should_not_be_called,
563 : httpcli_post_should_not_be_called);
564 1 : grpc_credentials_get_request_metadata(
565 : &exec_ctx, compute_engine_creds, NULL, test_service_url,
566 : on_oauth2_creds_get_metadata_success, (void *)test_user_data);
567 1 : grpc_exec_ctx_finish(&exec_ctx);
568 :
569 1 : grpc_credentials_unref(compute_engine_creds);
570 1 : grpc_httpcli_set_override(NULL, NULL);
571 1 : }
572 :
573 1 : static void test_compute_engine_creds_failure(void) {
574 1 : grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
575 1 : grpc_credentials *compute_engine_creds =
576 : grpc_google_compute_engine_credentials_create(NULL);
577 1 : grpc_httpcli_set_override(compute_engine_httpcli_get_failure_override,
578 : httpcli_post_should_not_be_called);
579 1 : GPR_ASSERT(grpc_credentials_has_request_metadata(compute_engine_creds));
580 1 : GPR_ASSERT(grpc_credentials_has_request_metadata_only(compute_engine_creds));
581 1 : grpc_credentials_get_request_metadata(
582 : &exec_ctx, compute_engine_creds, NULL, test_service_url,
583 : on_oauth2_creds_get_metadata_failure, (void *)test_user_data);
584 1 : grpc_credentials_unref(compute_engine_creds);
585 1 : grpc_httpcli_set_override(NULL, NULL);
586 1 : grpc_exec_ctx_finish(&exec_ctx);
587 1 : }
588 :
589 2 : static void validate_refresh_token_http_request(
590 : const grpc_httpcli_request *request, const char *body, size_t body_size) {
591 : /* The content of the assertion is tested extensively in json_token_test. */
592 2 : char *expected_body = NULL;
593 2 : GPR_ASSERT(body != NULL);
594 2 : GPR_ASSERT(body_size != 0);
595 2 : gpr_asprintf(&expected_body, GRPC_REFRESH_TOKEN_POST_BODY_FORMAT_STRING,
596 : "32555999999.apps.googleusercontent.com",
597 : "EmssLNjJy1332hD4KFsecret",
598 : "1/Blahblasj424jladJDSGNf-u4Sua3HDA2ngjd42");
599 2 : GPR_ASSERT(strlen(expected_body) == body_size);
600 2 : GPR_ASSERT(memcmp(expected_body, body, body_size) == 0);
601 2 : gpr_free(expected_body);
602 2 : GPR_ASSERT(request->handshaker == &grpc_httpcli_ssl);
603 2 : GPR_ASSERT(strcmp(request->host, GRPC_GOOGLE_OAUTH2_SERVICE_HOST) == 0);
604 2 : GPR_ASSERT(strcmp(request->path, GRPC_GOOGLE_OAUTH2_SERVICE_TOKEN_PATH) == 0);
605 2 : GPR_ASSERT(request->hdr_count == 1);
606 2 : GPR_ASSERT(strcmp(request->hdrs[0].key, "Content-Type") == 0);
607 2 : GPR_ASSERT(
608 : strcmp(request->hdrs[0].value, "application/x-www-form-urlencoded") == 0);
609 2 : }
610 :
611 1 : static int refresh_token_httpcli_post_success(
612 : grpc_exec_ctx *exec_ctx, const grpc_httpcli_request *request,
613 : const char *body, size_t body_size, gpr_timespec deadline,
614 : grpc_httpcli_response_cb on_response, void *user_data) {
615 1 : grpc_httpcli_response response =
616 : http_response(200, valid_oauth2_json_response);
617 1 : validate_refresh_token_http_request(request, body, body_size);
618 1 : on_response(exec_ctx, user_data, &response);
619 1 : return 1;
620 : }
621 :
622 1 : static int refresh_token_httpcli_post_failure(
623 : grpc_exec_ctx *exec_ctx, const grpc_httpcli_request *request,
624 : const char *body, size_t body_size, gpr_timespec deadline,
625 : grpc_httpcli_response_cb on_response, void *user_data) {
626 1 : grpc_httpcli_response response = http_response(403, "Not Authorized.");
627 1 : validate_refresh_token_http_request(request, body, body_size);
628 1 : on_response(exec_ctx, user_data, &response);
629 1 : return 1;
630 : }
631 :
632 1 : static void test_refresh_token_creds_success(void) {
633 1 : grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
634 1 : grpc_credentials *refresh_token_creds =
635 : grpc_google_refresh_token_credentials_create(test_refresh_token_str,
636 : NULL);
637 1 : GPR_ASSERT(grpc_credentials_has_request_metadata(refresh_token_creds));
638 1 : GPR_ASSERT(grpc_credentials_has_request_metadata_only(refresh_token_creds));
639 :
640 : /* First request: http get should be called. */
641 1 : grpc_httpcli_set_override(httpcli_get_should_not_be_called,
642 : refresh_token_httpcli_post_success);
643 1 : grpc_credentials_get_request_metadata(
644 : &exec_ctx, refresh_token_creds, NULL, test_service_url,
645 : on_oauth2_creds_get_metadata_success, (void *)test_user_data);
646 1 : grpc_exec_ctx_flush(&exec_ctx);
647 :
648 : /* Second request: the cached token should be served directly. */
649 1 : grpc_httpcli_set_override(httpcli_get_should_not_be_called,
650 : httpcli_post_should_not_be_called);
651 1 : grpc_credentials_get_request_metadata(
652 : &exec_ctx, refresh_token_creds, NULL, test_service_url,
653 : on_oauth2_creds_get_metadata_success, (void *)test_user_data);
654 1 : grpc_exec_ctx_flush(&exec_ctx);
655 :
656 1 : grpc_credentials_unref(refresh_token_creds);
657 1 : grpc_httpcli_set_override(NULL, NULL);
658 1 : grpc_exec_ctx_finish(&exec_ctx);
659 1 : }
660 :
661 1 : static void test_refresh_token_creds_failure(void) {
662 1 : grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
663 1 : grpc_credentials *refresh_token_creds =
664 : grpc_google_refresh_token_credentials_create(test_refresh_token_str,
665 : NULL);
666 1 : grpc_httpcli_set_override(httpcli_get_should_not_be_called,
667 : refresh_token_httpcli_post_failure);
668 1 : GPR_ASSERT(grpc_credentials_has_request_metadata(refresh_token_creds));
669 1 : GPR_ASSERT(grpc_credentials_has_request_metadata_only(refresh_token_creds));
670 1 : grpc_credentials_get_request_metadata(
671 : &exec_ctx, refresh_token_creds, NULL, test_service_url,
672 : on_oauth2_creds_get_metadata_failure, (void *)test_user_data);
673 1 : grpc_credentials_unref(refresh_token_creds);
674 1 : grpc_httpcli_set_override(NULL, NULL);
675 1 : grpc_exec_ctx_finish(&exec_ctx);
676 1 : }
677 :
678 3 : static void validate_jwt_encode_and_sign_params(
679 : const grpc_auth_json_key *json_key, const char *scope,
680 : gpr_timespec token_lifetime) {
681 3 : GPR_ASSERT(grpc_auth_json_key_is_valid(json_key));
682 3 : GPR_ASSERT(json_key->private_key != NULL);
683 3 : GPR_ASSERT(RSA_check_key(json_key->private_key));
684 3 : GPR_ASSERT(json_key->type != NULL &&
685 : strcmp(json_key->type, "service_account") == 0);
686 3 : GPR_ASSERT(json_key->private_key_id != NULL &&
687 : strcmp(json_key->private_key_id,
688 : "e6b5137873db8d2ef81e06a47289e6434ec8a165") == 0);
689 3 : GPR_ASSERT(json_key->client_id != NULL &&
690 : strcmp(json_key->client_id,
691 : "777-abaslkan11hlb6nmim3bpspl31ud.apps."
692 : "googleusercontent.com") == 0);
693 3 : GPR_ASSERT(json_key->client_email != NULL &&
694 : strcmp(json_key->client_email,
695 : "777-abaslkan11hlb6nmim3bpspl31ud@developer."
696 : "gserviceaccount.com") == 0);
697 3 : if (scope != NULL) GPR_ASSERT(strcmp(scope, test_scope) == 0);
698 3 : GPR_ASSERT(!gpr_time_cmp(token_lifetime, grpc_max_auth_token_lifetime));
699 3 : }
700 :
701 2 : static char *encode_and_sign_jwt_success(const grpc_auth_json_key *json_key,
702 : const char *audience,
703 : gpr_timespec token_lifetime,
704 : const char *scope) {
705 2 : validate_jwt_encode_and_sign_params(json_key, scope, token_lifetime);
706 2 : return gpr_strdup(test_signed_jwt);
707 : }
708 :
709 1 : static char *encode_and_sign_jwt_failure(const grpc_auth_json_key *json_key,
710 : const char *audience,
711 : gpr_timespec token_lifetime,
712 : const char *scope) {
713 1 : validate_jwt_encode_and_sign_params(json_key, scope, token_lifetime);
714 1 : return NULL;
715 : }
716 :
717 0 : static char *encode_and_sign_jwt_should_not_be_called(
718 : const grpc_auth_json_key *json_key, const char *audience,
719 : gpr_timespec token_lifetime, const char *scope) {
720 0 : GPR_ASSERT("grpc_jwt_encode_and_sign should not be called" == NULL);
721 : return NULL;
722 : }
723 :
724 3 : static void on_jwt_creds_get_metadata_success(grpc_exec_ctx *exec_ctx,
725 : void *user_data,
726 : grpc_credentials_md *md_elems,
727 : size_t num_md,
728 : grpc_credentials_status status) {
729 : char *expected_md_value;
730 3 : gpr_asprintf(&expected_md_value, "Bearer %s", test_signed_jwt);
731 3 : GPR_ASSERT(status == GRPC_CREDENTIALS_OK);
732 3 : GPR_ASSERT(num_md == 1);
733 3 : GPR_ASSERT(gpr_slice_str_cmp(md_elems[0].key, "Authorization") == 0);
734 3 : GPR_ASSERT(gpr_slice_str_cmp(md_elems[0].value, expected_md_value) == 0);
735 3 : GPR_ASSERT(user_data != NULL);
736 3 : GPR_ASSERT(strcmp((const char *)user_data, test_user_data) == 0);
737 3 : gpr_free(expected_md_value);
738 3 : }
739 :
740 1 : static void on_jwt_creds_get_metadata_failure(grpc_exec_ctx *exec_ctx,
741 : void *user_data,
742 : grpc_credentials_md *md_elems,
743 : size_t num_md,
744 : grpc_credentials_status status) {
745 1 : GPR_ASSERT(status == GRPC_CREDENTIALS_ERROR);
746 1 : GPR_ASSERT(num_md == 0);
747 1 : GPR_ASSERT(user_data != NULL);
748 1 : GPR_ASSERT(strcmp((const char *)user_data, test_user_data) == 0);
749 1 : }
750 :
751 1 : static void test_jwt_creds_success(void) {
752 1 : char *json_key_string = test_json_key_str();
753 1 : grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
754 1 : grpc_credentials *jwt_creds =
755 : grpc_service_account_jwt_access_credentials_create(
756 : json_key_string, grpc_max_auth_token_lifetime, NULL);
757 1 : GPR_ASSERT(grpc_credentials_has_request_metadata(jwt_creds));
758 1 : GPR_ASSERT(grpc_credentials_has_request_metadata_only(jwt_creds));
759 :
760 : /* First request: jwt_encode_and_sign should be called. */
761 1 : grpc_jwt_encode_and_sign_set_override(encode_and_sign_jwt_success);
762 1 : grpc_credentials_get_request_metadata(
763 : &exec_ctx, jwt_creds, NULL, test_service_url,
764 : on_jwt_creds_get_metadata_success, (void *)test_user_data);
765 1 : grpc_exec_ctx_flush(&exec_ctx);
766 :
767 : /* Second request: the cached token should be served directly. */
768 1 : grpc_jwt_encode_and_sign_set_override(
769 : encode_and_sign_jwt_should_not_be_called);
770 1 : grpc_credentials_get_request_metadata(
771 : &exec_ctx, jwt_creds, NULL, test_service_url,
772 : on_jwt_creds_get_metadata_success, (void *)test_user_data);
773 1 : grpc_exec_ctx_flush(&exec_ctx);
774 :
775 : /* Third request: Different service url so jwt_encode_and_sign should be
776 : called again (no caching). */
777 1 : grpc_jwt_encode_and_sign_set_override(encode_and_sign_jwt_success);
778 1 : grpc_credentials_get_request_metadata(
779 : &exec_ctx, jwt_creds, NULL, other_test_service_url,
780 : on_jwt_creds_get_metadata_success, (void *)test_user_data);
781 1 : grpc_exec_ctx_flush(&exec_ctx);
782 :
783 1 : gpr_free(json_key_string);
784 1 : grpc_credentials_unref(jwt_creds);
785 1 : grpc_jwt_encode_and_sign_set_override(NULL);
786 1 : }
787 :
788 1 : static void test_jwt_creds_signing_failure(void) {
789 1 : char *json_key_string = test_json_key_str();
790 1 : grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
791 1 : grpc_credentials *jwt_creds =
792 : grpc_service_account_jwt_access_credentials_create(
793 : json_key_string, grpc_max_auth_token_lifetime, NULL);
794 1 : GPR_ASSERT(grpc_credentials_has_request_metadata(jwt_creds));
795 1 : GPR_ASSERT(grpc_credentials_has_request_metadata_only(jwt_creds));
796 :
797 1 : grpc_jwt_encode_and_sign_set_override(encode_and_sign_jwt_failure);
798 1 : grpc_credentials_get_request_metadata(
799 : &exec_ctx, jwt_creds, NULL, test_service_url,
800 : on_jwt_creds_get_metadata_failure, (void *)test_user_data);
801 :
802 1 : gpr_free(json_key_string);
803 1 : grpc_credentials_unref(jwt_creds);
804 1 : grpc_jwt_encode_and_sign_set_override(NULL);
805 1 : grpc_exec_ctx_finish(&exec_ctx);
806 1 : }
807 :
808 2 : static void set_google_default_creds_env_var_with_file_contents(
809 : const char *file_prefix, const char *contents) {
810 2 : size_t contents_len = strlen(contents);
811 : char *creds_file_name;
812 2 : FILE *creds_file = gpr_tmpfile(file_prefix, &creds_file_name);
813 2 : GPR_ASSERT(creds_file_name != NULL);
814 2 : GPR_ASSERT(creds_file != NULL);
815 2 : GPR_ASSERT(fwrite(contents, 1, contents_len, creds_file) == contents_len);
816 2 : fclose(creds_file);
817 2 : gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, creds_file_name);
818 2 : gpr_free(creds_file_name);
819 2 : }
820 :
821 2 : static grpc_credentials *composite_inner_creds(grpc_credentials *creds,
822 : const char *inner_creds_type) {
823 : size_t i;
824 : grpc_composite_credentials *composite;
825 2 : GPR_ASSERT(strcmp(creds->type, GRPC_CREDENTIALS_TYPE_COMPOSITE) == 0);
826 2 : composite = (grpc_composite_credentials *)creds;
827 4 : for (i = 0; i < composite->inner.num_creds; i++) {
828 4 : grpc_credentials *c = composite->inner.creds_array[i];
829 6 : if (strcmp(c->type, inner_creds_type) == 0) return c;
830 : }
831 0 : GPR_ASSERT(0); /* Not found. */
832 : }
833 :
834 1 : static void test_google_default_creds_auth_key(void) {
835 : grpc_service_account_jwt_access_credentials *jwt;
836 : grpc_credentials *creds;
837 1 : char *json_key = test_json_key_str();
838 1 : grpc_flush_cached_google_default_credentials();
839 1 : set_google_default_creds_env_var_with_file_contents(
840 : "json_key_google_default_creds", json_key);
841 1 : gpr_free(json_key);
842 1 : creds = grpc_google_default_credentials_create();
843 1 : GPR_ASSERT(creds != NULL);
844 1 : jwt = (grpc_service_account_jwt_access_credentials *)composite_inner_creds(
845 : creds, GRPC_CREDENTIALS_TYPE_JWT);
846 1 : GPR_ASSERT(
847 : strcmp(jwt->key.client_id,
848 : "777-abaslkan11hlb6nmim3bpspl31ud.apps.googleusercontent.com") ==
849 : 0);
850 1 : grpc_credentials_unref(creds);
851 1 : gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, ""); /* Reset. */
852 1 : }
853 :
854 1 : static void test_google_default_creds_access_token(void) {
855 : grpc_google_refresh_token_credentials *refresh;
856 : grpc_credentials *creds;
857 1 : grpc_flush_cached_google_default_credentials();
858 1 : set_google_default_creds_env_var_with_file_contents(
859 : "refresh_token_google_default_creds", test_refresh_token_str);
860 1 : creds = grpc_google_default_credentials_create();
861 1 : GPR_ASSERT(creds != NULL);
862 1 : refresh = (grpc_google_refresh_token_credentials *)composite_inner_creds(
863 : creds, GRPC_CREDENTIALS_TYPE_OAUTH2);
864 1 : GPR_ASSERT(strcmp(refresh->refresh_token.client_id,
865 : "32555999999.apps.googleusercontent.com") == 0);
866 1 : grpc_credentials_unref(creds);
867 1 : gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, ""); /* Reset. */
868 1 : }
869 :
870 : typedef enum {
871 : PLUGIN_INITIAL_STATE,
872 : PLUGIN_GET_METADATA_CALLED_STATE,
873 : PLUGIN_DESTROY_CALLED_STATE
874 : } plugin_state;
875 :
876 : typedef struct {
877 : const char *key;
878 : const char *value;
879 : } plugin_metadata;
880 :
881 : static const plugin_metadata plugin_md[] = {{"foo", "bar"}, {"hi", "there"}};
882 :
883 1 : static void plugin_get_metadata_success(void *state, const char *service_url,
884 : grpc_credentials_plugin_metadata_cb cb,
885 : void *user_data) {
886 : size_t i;
887 : grpc_metadata md[GPR_ARRAY_SIZE(plugin_md)];
888 1 : plugin_state *s = (plugin_state *)state;
889 1 : GPR_ASSERT(strcmp(service_url, test_service_url) == 0);
890 1 : *s = PLUGIN_GET_METADATA_CALLED_STATE;
891 3 : for (i = 0; i < GPR_ARRAY_SIZE(plugin_md); i++) {
892 2 : memset(&md[i], 0, sizeof(grpc_metadata));
893 2 : md[i].key = plugin_md[i].key;
894 2 : md[i].value = plugin_md[i].value;
895 2 : md[i].value_length = strlen(plugin_md[i].value);
896 : }
897 1 : cb(user_data, md, GPR_ARRAY_SIZE(md), GRPC_STATUS_OK, NULL);
898 1 : }
899 :
900 1 : static void plugin_get_metadata_failure(void *state, const char *service_url,
901 : grpc_credentials_plugin_metadata_cb cb,
902 : void *user_data) {
903 1 : plugin_state *s = (plugin_state *)state;
904 1 : GPR_ASSERT(strcmp(service_url, test_service_url) == 0);
905 1 : *s = PLUGIN_GET_METADATA_CALLED_STATE;
906 1 : cb(user_data, NULL, 0, GRPC_STATUS_UNAUTHENTICATED,
907 : "Could not get metadata for plugin.");
908 1 : }
909 :
910 1 : static void on_plugin_metadata_received_success(
911 : grpc_exec_ctx *exec_ctx, void *user_data, grpc_credentials_md *md_elems,
912 : size_t num_md, grpc_credentials_status status) {
913 1 : size_t i = 0;
914 1 : GPR_ASSERT(user_data == NULL);
915 1 : GPR_ASSERT(md_elems != NULL);
916 1 : GPR_ASSERT(num_md == GPR_ARRAY_SIZE(plugin_md));
917 3 : for (i = 0; i < num_md; i++) {
918 2 : GPR_ASSERT(gpr_slice_str_cmp(md_elems[i].key, plugin_md[i].key) == 0);
919 2 : GPR_ASSERT(gpr_slice_str_cmp(md_elems[i].value, plugin_md[i].value) == 0);
920 : }
921 1 : }
922 :
923 1 : static void on_plugin_metadata_received_failure(
924 : grpc_exec_ctx *exec_ctx, void *user_data, grpc_credentials_md *md_elems,
925 : size_t num_md, grpc_credentials_status status) {
926 1 : GPR_ASSERT(user_data == NULL);
927 1 : GPR_ASSERT(md_elems == NULL);
928 1 : GPR_ASSERT(num_md == 0);
929 1 : GPR_ASSERT(status == GRPC_CREDENTIALS_ERROR);
930 1 : }
931 :
932 2 : static void plugin_destroy(void *state) {
933 2 : plugin_state *s = (plugin_state *)state;
934 2 : *s = PLUGIN_DESTROY_CALLED_STATE;
935 2 : }
936 :
937 1 : static void test_metadata_plugin_success(void) {
938 : grpc_credentials *creds;
939 1 : plugin_state state = PLUGIN_INITIAL_STATE;
940 : grpc_metadata_credentials_plugin plugin;
941 1 : grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
942 :
943 1 : plugin.state = &state;
944 1 : plugin.get_metadata = plugin_get_metadata_success;
945 1 : plugin.destroy = plugin_destroy;
946 :
947 1 : creds = grpc_metadata_credentials_create_from_plugin(plugin, NULL);
948 1 : GPR_ASSERT(state == PLUGIN_INITIAL_STATE);
949 1 : grpc_credentials_get_request_metadata(
950 : &exec_ctx, creds, NULL, test_service_url,
951 : on_plugin_metadata_received_success, NULL);
952 1 : GPR_ASSERT(state == PLUGIN_GET_METADATA_CALLED_STATE);
953 1 : grpc_credentials_release(creds);
954 1 : GPR_ASSERT(state == PLUGIN_DESTROY_CALLED_STATE);
955 1 : grpc_exec_ctx_finish(&exec_ctx);
956 1 : }
957 :
958 1 : static void test_metadata_plugin_failure(void) {
959 : grpc_credentials *creds;
960 1 : plugin_state state = PLUGIN_INITIAL_STATE;
961 : grpc_metadata_credentials_plugin plugin;
962 1 : grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
963 :
964 1 : plugin.state = &state;
965 1 : plugin.get_metadata = plugin_get_metadata_failure;
966 1 : plugin.destroy = plugin_destroy;
967 :
968 1 : creds = grpc_metadata_credentials_create_from_plugin(plugin, NULL);
969 1 : GPR_ASSERT(state == PLUGIN_INITIAL_STATE);
970 1 : grpc_credentials_get_request_metadata(
971 : &exec_ctx, creds, NULL, test_service_url,
972 : on_plugin_metadata_received_failure, NULL);
973 1 : GPR_ASSERT(state == PLUGIN_GET_METADATA_CALLED_STATE);
974 1 : grpc_credentials_release(creds);
975 1 : GPR_ASSERT(state == PLUGIN_DESTROY_CALLED_STATE);
976 1 : grpc_exec_ctx_finish(&exec_ctx);
977 1 : }
978 :
979 1 : int main(int argc, char **argv) {
980 1 : grpc_test_init(argc, argv);
981 1 : test_empty_md_store();
982 1 : test_ref_unref_empty_md_store();
983 1 : test_add_to_empty_md_store();
984 1 : test_add_cstrings_to_empty_md_store();
985 1 : test_empty_preallocated_md_store();
986 1 : test_add_abunch_to_md_store();
987 1 : test_oauth2_token_fetcher_creds_parsing_ok();
988 1 : test_oauth2_token_fetcher_creds_parsing_bad_http_status();
989 1 : test_oauth2_token_fetcher_creds_parsing_empty_http_body();
990 1 : test_oauth2_token_fetcher_creds_parsing_invalid_json();
991 1 : test_oauth2_token_fetcher_creds_parsing_missing_token();
992 1 : test_oauth2_token_fetcher_creds_parsing_missing_token_type();
993 1 : test_oauth2_token_fetcher_creds_parsing_missing_token_lifetime();
994 1 : test_google_iam_creds();
995 1 : test_access_token_creds();
996 1 : test_ssl_oauth2_composite_creds();
997 1 : test_ssl_oauth2_google_iam_composite_creds();
998 1 : test_compute_engine_creds_success();
999 1 : test_compute_engine_creds_failure();
1000 1 : test_refresh_token_creds_success();
1001 1 : test_refresh_token_creds_failure();
1002 1 : test_jwt_creds_success();
1003 1 : test_jwt_creds_signing_failure();
1004 1 : test_google_default_creds_auth_key();
1005 1 : test_google_default_creds_access_token();
1006 1 : test_metadata_plugin_success();
1007 1 : test_metadata_plugin_failure();
1008 1 : return 0;
1009 : }
|