Julien Boeuf | 87047d7 | 2015-08-21 14:30:33 -0700 | [diff] [blame] | 1 | /* |
| 2 | * |
Craig Tiller | 6169d5f | 2016-03-31 07:46:18 -0700 | [diff] [blame] | 3 | * Copyright 2015, Google Inc. |
Julien Boeuf | 87047d7 | 2015-08-21 14:30:33 -0700 | [diff] [blame] | 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 | |
Mark D. Roth | 071cacf | 2016-11-17 13:17:56 -0800 | [diff] [blame] | 34 | #include "src/core/lib/security/transport/security_handshaker.h" |
Julien Boeuf | 87047d7 | 2015-08-21 14:30:33 -0700 | [diff] [blame] | 35 | |
Julien Boeuf | 4f4d37c | 2016-02-24 22:07:36 -0800 | [diff] [blame] | 36 | #include <stdbool.h> |
Julien Boeuf | 87047d7 | 2015-08-21 14:30:33 -0700 | [diff] [blame] | 37 | #include <string.h> |
| 38 | |
Craig Tiller | 28b7242 | 2016-10-26 21:15:29 -0700 | [diff] [blame] | 39 | #include <grpc/slice_buffer.h> |
Julien Boeuf | 87047d7 | 2015-08-21 14:30:33 -0700 | [diff] [blame] | 40 | #include <grpc/support/alloc.h> |
| 41 | #include <grpc/support/log.h> |
Mark D. Roth | 963be37 | 2016-11-16 14:17:06 -0800 | [diff] [blame] | 42 | |
| 43 | #include "src/core/lib/channel/channel_args.h" |
| 44 | #include "src/core/lib/channel/handshaker.h" |
Mark D. Roth | 1f0f23c | 2017-01-06 13:07:19 -0800 | [diff] [blame] | 45 | #include "src/core/lib/channel/handshaker_registry.h" |
Julien Boeuf | 8ca294e | 2016-05-02 14:56:30 -0700 | [diff] [blame] | 46 | #include "src/core/lib/security/context/security_context.h" |
| 47 | #include "src/core/lib/security/transport/secure_endpoint.h" |
Craig Tiller | 804ff71 | 2016-05-05 16:25:40 -0700 | [diff] [blame] | 48 | #include "src/core/lib/security/transport/tsi_error.h" |
Craig Tiller | 6822a7a | 2016-12-06 19:28:52 -0800 | [diff] [blame] | 49 | #include "src/core/lib/slice/slice_internal.h" |
Julien Boeuf | 87047d7 | 2015-08-21 14:30:33 -0700 | [diff] [blame] | 50 | |
| 51 | #define GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE 256 |
| 52 | |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 53 | typedef struct { |
Mark D. Roth | 963be37 | 2016-11-16 14:17:06 -0800 | [diff] [blame] | 54 | grpc_handshaker base; |
Mark D. Roth | 75d0c42 | 2016-11-30 11:40:57 -0800 | [diff] [blame] | 55 | |
| 56 | // State set at creation time. |
Julien Boeuf | db5282b | 2015-08-21 15:23:52 -0700 | [diff] [blame] | 57 | tsi_handshaker *handshaker; |
Mark D. Roth | 75d0c42 | 2016-11-30 11:40:57 -0800 | [diff] [blame] | 58 | grpc_security_connector *connector; |
| 59 | |
Mark D. Roth | 3beb6c5 | 2016-11-29 11:25:12 -0800 | [diff] [blame] | 60 | gpr_mu mu; |
| 61 | gpr_refcount refs; |
Mark D. Roth | 75d0c42 | 2016-11-30 11:40:57 -0800 | [diff] [blame] | 62 | |
| 63 | bool shutdown; |
| 64 | // Endpoint and read buffer to destroy after a shutdown. |
| 65 | grpc_endpoint *endpoint_to_destroy; |
| 66 | grpc_slice_buffer *read_buffer_to_destroy; |
| 67 | |
| 68 | // State saved while performing the handshake. |
Mark D. Roth | a561785 | 2016-12-01 08:48:22 -0800 | [diff] [blame] | 69 | grpc_handshaker_args *args; |
| 70 | grpc_closure *on_handshake_done; |
Mark D. Roth | 75d0c42 | 2016-11-30 11:40:57 -0800 | [diff] [blame] | 71 | |
Julien Boeuf | 87047d7 | 2015-08-21 14:30:33 -0700 | [diff] [blame] | 72 | unsigned char *handshake_buffer; |
| 73 | size_t handshake_buffer_size; |
Craig Tiller | d41a4a7 | 2016-10-26 16:16:06 -0700 | [diff] [blame] | 74 | grpc_slice_buffer left_overs; |
Craig Tiller | d41a4a7 | 2016-10-26 16:16:06 -0700 | [diff] [blame] | 75 | grpc_slice_buffer outgoing; |
Craig Tiller | 10ee274 | 2015-09-22 09:25:57 -0700 | [diff] [blame] | 76 | grpc_closure on_handshake_data_sent_to_peer; |
| 77 | grpc_closure on_handshake_data_received_from_peer; |
Mark D. Roth | 3beb6c5 | 2016-11-29 11:25:12 -0800 | [diff] [blame] | 78 | grpc_closure on_peer_checked; |
Julien Boeuf | 366f42c | 2015-12-16 22:05:46 -0800 | [diff] [blame] | 79 | grpc_auth_context *auth_context; |
Mark D. Roth | 963be37 | 2016-11-16 14:17:06 -0800 | [diff] [blame] | 80 | } security_handshaker; |
Julien Boeuf | 87047d7 | 2015-08-21 14:30:33 -0700 | [diff] [blame] | 81 | |
Mark D. Roth | 75d0c42 | 2016-11-30 11:40:57 -0800 | [diff] [blame] | 82 | static void security_handshaker_unref(grpc_exec_ctx *exec_ctx, |
| 83 | security_handshaker *h) { |
Craig Tiller | fc25b5f | 2016-06-14 09:50:15 -0700 | [diff] [blame] | 84 | if (gpr_unref(&h->refs)) { |
Mark D. Roth | 3beb6c5 | 2016-11-29 11:25:12 -0800 | [diff] [blame] | 85 | gpr_mu_destroy(&h->mu); |
Mark D. Roth | bd913a8 | 2016-12-02 16:47:35 +0000 | [diff] [blame] | 86 | tsi_handshaker_destroy(h->handshaker); |
Mark D. Roth | 75d0c42 | 2016-11-30 11:40:57 -0800 | [diff] [blame] | 87 | if (h->endpoint_to_destroy != NULL) { |
| 88 | grpc_endpoint_destroy(exec_ctx, h->endpoint_to_destroy); |
| 89 | } |
| 90 | if (h->read_buffer_to_destroy != NULL) { |
Craig Tiller | 6822a7a | 2016-12-06 19:28:52 -0800 | [diff] [blame] | 91 | grpc_slice_buffer_destroy_internal(exec_ctx, h->read_buffer_to_destroy); |
Mark D. Roth | 75d0c42 | 2016-11-30 11:40:57 -0800 | [diff] [blame] | 92 | gpr_free(h->read_buffer_to_destroy); |
| 93 | } |
Mark D. Roth | bd913a8 | 2016-12-02 16:47:35 +0000 | [diff] [blame] | 94 | gpr_free(h->handshake_buffer); |
Craig Tiller | 6822a7a | 2016-12-06 19:28:52 -0800 | [diff] [blame] | 95 | grpc_slice_buffer_destroy_internal(exec_ctx, &h->left_overs); |
| 96 | grpc_slice_buffer_destroy_internal(exec_ctx, &h->outgoing); |
Craig Tiller | fc25b5f | 2016-06-14 09:50:15 -0700 | [diff] [blame] | 97 | GRPC_AUTH_CONTEXT_UNREF(h->auth_context, "handshake"); |
Craig Tiller | 397bff3 | 2016-12-06 15:05:59 -0800 | [diff] [blame] | 98 | GRPC_SECURITY_CONNECTOR_UNREF(exec_ctx, h->connector, "handshake"); |
Craig Tiller | fc25b5f | 2016-06-14 09:50:15 -0700 | [diff] [blame] | 99 | gpr_free(h); |
| 100 | } |
| 101 | } |
| 102 | |
Mark D. Roth | 75d0c42 | 2016-11-30 11:40:57 -0800 | [diff] [blame] | 103 | // Set args fields to NULL, saving the endpoint and read buffer for |
| 104 | // later destruction. |
Craig Tiller | b6821f6 | 2016-12-06 15:10:42 -0800 | [diff] [blame] | 105 | static void cleanup_args_for_failure_locked(grpc_exec_ctx *exec_ctx, |
| 106 | security_handshaker *h) { |
Mark D. Roth | 75d0c42 | 2016-11-30 11:40:57 -0800 | [diff] [blame] | 107 | h->endpoint_to_destroy = h->args->endpoint; |
| 108 | h->args->endpoint = NULL; |
| 109 | h->read_buffer_to_destroy = h->args->read_buffer; |
| 110 | h->args->read_buffer = NULL; |
Craig Tiller | 397bff3 | 2016-12-06 15:05:59 -0800 | [diff] [blame] | 111 | grpc_channel_args_destroy(exec_ctx, h->args->args); |
Mark D. Roth | 75d0c42 | 2016-11-30 11:40:57 -0800 | [diff] [blame] | 112 | h->args->args = NULL; |
| 113 | } |
| 114 | |
| 115 | // If the handshake failed or we're shutting down, clean up and invoke the |
| 116 | // callback with the error. |
| 117 | static void security_handshake_failed_locked(grpc_exec_ctx *exec_ctx, |
| 118 | security_handshaker *h, |
| 119 | grpc_error *error) { |
Craig Tiller | 804ff71 | 2016-05-05 16:25:40 -0700 | [diff] [blame] | 120 | if (error == GRPC_ERROR_NONE) { |
Mark D. Roth | 75d0c42 | 2016-11-30 11:40:57 -0800 | [diff] [blame] | 121 | // If we were shut down after the handshake succeeded but before an |
| 122 | // endpoint callback was invoked, we need to generate our own error. |
| 123 | error = GRPC_ERROR_CREATE("Handshaker shutdown"); |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 124 | } |
Mark D. Roth | 75d0c42 | 2016-11-30 11:40:57 -0800 | [diff] [blame] | 125 | const char *msg = grpc_error_string(error); |
| 126 | gpr_log(GPR_DEBUG, "Security handshake failed: %s", msg); |
Craig Tiller | 7c70b6c | 2017-01-23 07:48:42 -0800 | [diff] [blame] | 127 | |
Mark D. Roth | 75d0c42 | 2016-11-30 11:40:57 -0800 | [diff] [blame] | 128 | if (!h->shutdown) { |
| 129 | // TODO(ctiller): It is currently necessary to shutdown endpoints |
| 130 | // before destroying them, even if we know that there are no |
| 131 | // pending read/write callbacks. This should be fixed, at which |
| 132 | // point this can be removed. |
Craig Tiller | cda759d | 2017-01-27 11:37:37 -0800 | [diff] [blame] | 133 | grpc_endpoint_shutdown(exec_ctx, h->args->endpoint, GRPC_ERROR_REF(error)); |
Mark D. Roth | 75d0c42 | 2016-11-30 11:40:57 -0800 | [diff] [blame] | 134 | // Not shutting down, so the write failed. Clean up before |
| 135 | // invoking the callback. |
Craig Tiller | 397bff3 | 2016-12-06 15:05:59 -0800 | [diff] [blame] | 136 | cleanup_args_for_failure_locked(exec_ctx, h); |
Mark D. Roth | c898417 | 2016-12-08 09:40:33 -0800 | [diff] [blame] | 137 | // Set shutdown to true so that subsequent calls to |
| 138 | // security_handshaker_shutdown() do nothing. |
| 139 | h->shutdown = true; |
Mark D. Roth | 75d0c42 | 2016-11-30 11:40:57 -0800 | [diff] [blame] | 140 | } |
| 141 | // Invoke callback. |
Craig Tiller | 91031da | 2016-12-28 15:44:25 -0800 | [diff] [blame] | 142 | grpc_closure_sched(exec_ctx, h->on_handshake_done, error); |
Julien Boeuf | 87047d7 | 2015-08-21 14:30:33 -0700 | [diff] [blame] | 143 | } |
| 144 | |
Mark D. Roth | 3beb6c5 | 2016-11-29 11:25:12 -0800 | [diff] [blame] | 145 | static void on_peer_checked(grpc_exec_ctx *exec_ctx, void *arg, |
| 146 | grpc_error *error) { |
| 147 | security_handshaker *h = arg; |
| 148 | gpr_mu_lock(&h->mu); |
Mark D. Roth | 75d0c42 | 2016-11-30 11:40:57 -0800 | [diff] [blame] | 149 | if (error != GRPC_ERROR_NONE || h->shutdown) { |
| 150 | security_handshake_failed_locked(exec_ctx, h, GRPC_ERROR_REF(error)); |
Mark D. Roth | 3beb6c5 | 2016-11-29 11:25:12 -0800 | [diff] [blame] | 151 | goto done; |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 152 | } |
Mark D. Roth | 3beb6c5 | 2016-11-29 11:25:12 -0800 | [diff] [blame] | 153 | // Get frame protector. |
| 154 | tsi_frame_protector *protector; |
| 155 | tsi_result result = |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 156 | tsi_handshaker_create_frame_protector(h->handshaker, NULL, &protector); |
| 157 | if (result != TSI_OK) { |
Mark D. Roth | 3beb6c5 | 2016-11-29 11:25:12 -0800 | [diff] [blame] | 158 | error = grpc_set_tsi_error_result( |
| 159 | GRPC_ERROR_CREATE("Frame protector creation failed"), result); |
Mark D. Roth | 75d0c42 | 2016-11-30 11:40:57 -0800 | [diff] [blame] | 160 | security_handshake_failed_locked(exec_ctx, h, error); |
Mark D. Roth | 3beb6c5 | 2016-11-29 11:25:12 -0800 | [diff] [blame] | 161 | goto done; |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 162 | } |
Mark D. Roth | 75d0c42 | 2016-11-30 11:40:57 -0800 | [diff] [blame] | 163 | // Success. |
| 164 | // Create secure endpoint. |
Mark D. Roth | a561785 | 2016-12-01 08:48:22 -0800 | [diff] [blame] | 165 | h->args->endpoint = grpc_secure_endpoint_create( |
| 166 | protector, h->args->endpoint, h->left_overs.slices, h->left_overs.count); |
Julien Boeuf | e9961d2 | 2015-09-15 22:51:02 -0700 | [diff] [blame] | 167 | h->left_overs.count = 0; |
| 168 | h->left_overs.length = 0; |
Mark D. Roth | 75d0c42 | 2016-11-30 11:40:57 -0800 | [diff] [blame] | 169 | // Clear out the read buffer before it gets passed to the transport, |
| 170 | // since any excess bytes were already copied to h->left_overs. |
Craig Tiller | 6822a7a | 2016-12-06 19:28:52 -0800 | [diff] [blame] | 171 | grpc_slice_buffer_reset_and_unref_internal(exec_ctx, h->args->read_buffer); |
Mark D. Roth | 75d0c42 | 2016-11-30 11:40:57 -0800 | [diff] [blame] | 172 | // Add auth context to channel args. |
| 173 | grpc_arg auth_context_arg = grpc_auth_context_to_arg(h->auth_context); |
Mark D. Roth | a561785 | 2016-12-01 08:48:22 -0800 | [diff] [blame] | 174 | grpc_channel_args *tmp_args = h->args->args; |
Mark D. Roth | 75d0c42 | 2016-11-30 11:40:57 -0800 | [diff] [blame] | 175 | h->args->args = |
| 176 | grpc_channel_args_copy_and_add(tmp_args, &auth_context_arg, 1); |
Craig Tiller | 397bff3 | 2016-12-06 15:05:59 -0800 | [diff] [blame] | 177 | grpc_channel_args_destroy(exec_ctx, tmp_args); |
Mark D. Roth | 75d0c42 | 2016-11-30 11:40:57 -0800 | [diff] [blame] | 178 | // Invoke callback. |
Craig Tiller | 91031da | 2016-12-28 15:44:25 -0800 | [diff] [blame] | 179 | grpc_closure_sched(exec_ctx, h->on_handshake_done, GRPC_ERROR_NONE); |
Mark D. Roth | 412e6ac | 2016-12-01 08:24:45 -0800 | [diff] [blame] | 180 | // Set shutdown to true so that subsequent calls to |
| 181 | // security_handshaker_shutdown() do nothing. |
| 182 | h->shutdown = true; |
Mark D. Roth | 3beb6c5 | 2016-11-29 11:25:12 -0800 | [diff] [blame] | 183 | done: |
Mark D. Roth | 3beb6c5 | 2016-11-29 11:25:12 -0800 | [diff] [blame] | 184 | gpr_mu_unlock(&h->mu); |
Mark D. Roth | 75d0c42 | 2016-11-30 11:40:57 -0800 | [diff] [blame] | 185 | security_handshaker_unref(exec_ctx, h); |
Julien Boeuf | 87047d7 | 2015-08-21 14:30:33 -0700 | [diff] [blame] | 186 | } |
| 187 | |
Mark D. Roth | a561785 | 2016-12-01 08:48:22 -0800 | [diff] [blame] | 188 | static grpc_error *check_peer_locked(grpc_exec_ctx *exec_ctx, |
Mark D. Roth | 3beb6c5 | 2016-11-29 11:25:12 -0800 | [diff] [blame] | 189 | security_handshaker *h) { |
Julien Boeuf | 87047d7 | 2015-08-21 14:30:33 -0700 | [diff] [blame] | 190 | tsi_peer peer; |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 191 | tsi_result result = tsi_handshaker_extract_peer(h->handshaker, &peer); |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 192 | if (result != TSI_OK) { |
Mark D. Roth | 3beb6c5 | 2016-11-29 11:25:12 -0800 | [diff] [blame] | 193 | return grpc_set_tsi_error_result( |
| 194 | GRPC_ERROR_CREATE("Peer extraction failed"), result); |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 195 | } |
Julien Boeuf | 366f42c | 2015-12-16 22:05:46 -0800 | [diff] [blame] | 196 | grpc_security_connector_check_peer(exec_ctx, h->connector, peer, |
Mark D. Roth | 3beb6c5 | 2016-11-29 11:25:12 -0800 | [diff] [blame] | 197 | &h->auth_context, &h->on_peer_checked); |
| 198 | return GRPC_ERROR_NONE; |
Julien Boeuf | 87047d7 | 2015-08-21 14:30:33 -0700 | [diff] [blame] | 199 | } |
| 200 | |
Mark D. Roth | a561785 | 2016-12-01 08:48:22 -0800 | [diff] [blame] | 201 | static grpc_error *send_handshake_bytes_to_peer_locked(grpc_exec_ctx *exec_ctx, |
Mark D. Roth | 3beb6c5 | 2016-11-29 11:25:12 -0800 | [diff] [blame] | 202 | security_handshaker *h) { |
| 203 | // Get data to send. |
Julien Boeuf | 87047d7 | 2015-08-21 14:30:33 -0700 | [diff] [blame] | 204 | tsi_result result = TSI_OK; |
Mark D. Roth | 3beb6c5 | 2016-11-29 11:25:12 -0800 | [diff] [blame] | 205 | size_t offset = 0; |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 206 | do { |
| 207 | size_t to_send_size = h->handshake_buffer_size - offset; |
| 208 | result = tsi_handshaker_get_bytes_to_send_to_peer( |
| 209 | h->handshaker, h->handshake_buffer + offset, &to_send_size); |
| 210 | offset += to_send_size; |
| 211 | if (result == TSI_INCOMPLETE_DATA) { |
| 212 | h->handshake_buffer_size *= 2; |
| 213 | h->handshake_buffer = |
| 214 | gpr_realloc(h->handshake_buffer, h->handshake_buffer_size); |
Julien Boeuf | 87047d7 | 2015-08-21 14:30:33 -0700 | [diff] [blame] | 215 | } |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 216 | } while (result == TSI_INCOMPLETE_DATA); |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 217 | if (result != TSI_OK) { |
Mark D. Roth | 3beb6c5 | 2016-11-29 11:25:12 -0800 | [diff] [blame] | 218 | return grpc_set_tsi_error_result(GRPC_ERROR_CREATE("Handshake failed"), |
| 219 | result); |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 220 | } |
Mark D. Roth | 3beb6c5 | 2016-11-29 11:25:12 -0800 | [diff] [blame] | 221 | // Send data. |
| 222 | grpc_slice to_send = |
Craig Tiller | d41a4a7 | 2016-10-26 16:16:06 -0700 | [diff] [blame] | 223 | grpc_slice_from_copied_buffer((const char *)h->handshake_buffer, offset); |
Craig Tiller | 6822a7a | 2016-12-06 19:28:52 -0800 | [diff] [blame] | 224 | grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &h->outgoing); |
Craig Tiller | d41a4a7 | 2016-10-26 16:16:06 -0700 | [diff] [blame] | 225 | grpc_slice_buffer_add(&h->outgoing, to_send); |
Mark D. Roth | 95fcb58 | 2016-11-29 11:29:19 -0800 | [diff] [blame] | 226 | grpc_endpoint_write(exec_ctx, h->args->endpoint, &h->outgoing, |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 227 | &h->on_handshake_data_sent_to_peer); |
Mark D. Roth | 3beb6c5 | 2016-11-29 11:25:12 -0800 | [diff] [blame] | 228 | return GRPC_ERROR_NONE; |
Julien Boeuf | 87047d7 | 2015-08-21 14:30:33 -0700 | [diff] [blame] | 229 | } |
| 230 | |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 231 | static void on_handshake_data_received_from_peer(grpc_exec_ctx *exec_ctx, |
Mark D. Roth | 75d0c42 | 2016-11-30 11:40:57 -0800 | [diff] [blame] | 232 | void *arg, grpc_error *error) { |
| 233 | security_handshaker *h = arg; |
Mark D. Roth | 3beb6c5 | 2016-11-29 11:25:12 -0800 | [diff] [blame] | 234 | gpr_mu_lock(&h->mu); |
Mark D. Roth | 75d0c42 | 2016-11-30 11:40:57 -0800 | [diff] [blame] | 235 | if (error != GRPC_ERROR_NONE || h->shutdown) { |
| 236 | security_handshake_failed_locked( |
Craig Tiller | 804ff71 | 2016-05-05 16:25:40 -0700 | [diff] [blame] | 237 | exec_ctx, h, |
| 238 | GRPC_ERROR_CREATE_REFERENCING("Handshake read failed", &error, 1)); |
Mark D. Roth | 3beb6c5 | 2016-11-29 11:25:12 -0800 | [diff] [blame] | 239 | gpr_mu_unlock(&h->mu); |
Mark D. Roth | 75d0c42 | 2016-11-30 11:40:57 -0800 | [diff] [blame] | 240 | security_handshaker_unref(exec_ctx, h); |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 241 | return; |
| 242 | } |
Mark D. Roth | 3beb6c5 | 2016-11-29 11:25:12 -0800 | [diff] [blame] | 243 | // Process received data. |
| 244 | tsi_result result = TSI_OK; |
| 245 | size_t consumed_slice_size = 0; |
| 246 | size_t i; |
Mark D. Roth | 963be37 | 2016-11-16 14:17:06 -0800 | [diff] [blame] | 247 | for (i = 0; i < h->args->read_buffer->count; i++) { |
| 248 | consumed_slice_size = GRPC_SLICE_LENGTH(h->args->read_buffer->slices[i]); |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 249 | result = tsi_handshaker_process_bytes_from_peer( |
Mark D. Roth | 963be37 | 2016-11-16 14:17:06 -0800 | [diff] [blame] | 250 | h->handshaker, GRPC_SLICE_START_PTR(h->args->read_buffer->slices[i]), |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 251 | &consumed_slice_size); |
| 252 | if (!tsi_handshaker_is_in_progress(h->handshaker)) break; |
| 253 | } |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 254 | if (tsi_handshaker_is_in_progress(h->handshaker)) { |
| 255 | /* We may need more data. */ |
| 256 | if (result == TSI_INCOMPLETE_DATA) { |
Mark D. Roth | 95fcb58 | 2016-11-29 11:29:19 -0800 | [diff] [blame] | 257 | grpc_endpoint_read(exec_ctx, h->args->endpoint, h->args->read_buffer, |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 258 | &h->on_handshake_data_received_from_peer); |
Mark D. Roth | 3beb6c5 | 2016-11-29 11:25:12 -0800 | [diff] [blame] | 259 | goto done; |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 260 | } else { |
Mark D. Roth | 3beb6c5 | 2016-11-29 11:25:12 -0800 | [diff] [blame] | 261 | error = send_handshake_bytes_to_peer_locked(exec_ctx, h); |
| 262 | if (error != GRPC_ERROR_NONE) { |
Mark D. Roth | 75d0c42 | 2016-11-30 11:40:57 -0800 | [diff] [blame] | 263 | security_handshake_failed_locked(exec_ctx, h, error); |
Mark D. Roth | 3beb6c5 | 2016-11-29 11:25:12 -0800 | [diff] [blame] | 264 | gpr_mu_unlock(&h->mu); |
Mark D. Roth | 75d0c42 | 2016-11-30 11:40:57 -0800 | [diff] [blame] | 265 | security_handshaker_unref(exec_ctx, h); |
Mark D. Roth | 3beb6c5 | 2016-11-29 11:25:12 -0800 | [diff] [blame] | 266 | return; |
| 267 | } |
| 268 | goto done; |
Julien Boeuf | 87047d7 | 2015-08-21 14:30:33 -0700 | [diff] [blame] | 269 | } |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 270 | } |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 271 | if (result != TSI_OK) { |
Mark D. Roth | 75d0c42 | 2016-11-30 11:40:57 -0800 | [diff] [blame] | 272 | security_handshake_failed_locked( |
Mark D. Roth | a561785 | 2016-12-01 08:48:22 -0800 | [diff] [blame] | 273 | exec_ctx, h, grpc_set_tsi_error_result( |
| 274 | GRPC_ERROR_CREATE("Handshake failed"), result)); |
Mark D. Roth | 3beb6c5 | 2016-11-29 11:25:12 -0800 | [diff] [blame] | 275 | gpr_mu_unlock(&h->mu); |
Mark D. Roth | 75d0c42 | 2016-11-30 11:40:57 -0800 | [diff] [blame] | 276 | security_handshaker_unref(exec_ctx, h); |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 277 | return; |
| 278 | } |
Julien Boeuf | 87047d7 | 2015-08-21 14:30:33 -0700 | [diff] [blame] | 279 | /* Handshake is done and successful this point. */ |
Mark D. Roth | 3beb6c5 | 2016-11-29 11:25:12 -0800 | [diff] [blame] | 280 | bool has_left_overs_in_current_slice = |
Mark D. Roth | 963be37 | 2016-11-16 14:17:06 -0800 | [diff] [blame] | 281 | (consumed_slice_size < |
| 282 | GRPC_SLICE_LENGTH(h->args->read_buffer->slices[i])); |
Mark D. Roth | a561785 | 2016-12-01 08:48:22 -0800 | [diff] [blame] | 283 | size_t num_left_overs = (has_left_overs_in_current_slice ? 1 : 0) + |
| 284 | h->args->read_buffer->count - i - 1; |
Mark D. Roth | 963be37 | 2016-11-16 14:17:06 -0800 | [diff] [blame] | 285 | if (num_left_overs > 0) { |
| 286 | /* Put the leftovers in our buffer (ownership transfered). */ |
| 287 | if (has_left_overs_in_current_slice) { |
| 288 | grpc_slice_buffer_add( |
| 289 | &h->left_overs, |
| 290 | grpc_slice_split_tail(&h->args->read_buffer->slices[i], |
Mark D. Roth | a561785 | 2016-12-01 08:48:22 -0800 | [diff] [blame] | 291 | consumed_slice_size)); |
Mark D. Roth | 963be37 | 2016-11-16 14:17:06 -0800 | [diff] [blame] | 292 | /* split_tail above increments refcount. */ |
Craig Tiller | 6822a7a | 2016-12-06 19:28:52 -0800 | [diff] [blame] | 293 | grpc_slice_unref_internal(exec_ctx, h->args->read_buffer->slices[i]); |
Mark D. Roth | 963be37 | 2016-11-16 14:17:06 -0800 | [diff] [blame] | 294 | } |
| 295 | grpc_slice_buffer_addn( |
| 296 | &h->left_overs, &h->args->read_buffer->slices[i + 1], |
| 297 | num_left_overs - (size_t)has_left_overs_in_current_slice); |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 298 | } |
Mark D. Roth | 3beb6c5 | 2016-11-29 11:25:12 -0800 | [diff] [blame] | 299 | // Check peer. |
| 300 | error = check_peer_locked(exec_ctx, h); |
| 301 | if (error != GRPC_ERROR_NONE) { |
Mark D. Roth | 75d0c42 | 2016-11-30 11:40:57 -0800 | [diff] [blame] | 302 | security_handshake_failed_locked(exec_ctx, h, error); |
Mark D. Roth | 3beb6c5 | 2016-11-29 11:25:12 -0800 | [diff] [blame] | 303 | gpr_mu_unlock(&h->mu); |
Mark D. Roth | 75d0c42 | 2016-11-30 11:40:57 -0800 | [diff] [blame] | 304 | security_handshaker_unref(exec_ctx, h); |
Mark D. Roth | 3beb6c5 | 2016-11-29 11:25:12 -0800 | [diff] [blame] | 305 | return; |
| 306 | } |
| 307 | done: |
| 308 | gpr_mu_unlock(&h->mu); |
Julien Boeuf | 87047d7 | 2015-08-21 14:30:33 -0700 | [diff] [blame] | 309 | } |
| 310 | |
Mark D. Roth | a561785 | 2016-12-01 08:48:22 -0800 | [diff] [blame] | 311 | static void on_handshake_data_sent_to_peer(grpc_exec_ctx *exec_ctx, void *arg, |
| 312 | grpc_error *error) { |
Mark D. Roth | 75d0c42 | 2016-11-30 11:40:57 -0800 | [diff] [blame] | 313 | security_handshaker *h = arg; |
| 314 | gpr_mu_lock(&h->mu); |
| 315 | if (error != GRPC_ERROR_NONE || h->shutdown) { |
| 316 | security_handshake_failed_locked( |
| 317 | exec_ctx, h, |
| 318 | GRPC_ERROR_CREATE_REFERENCING("Handshake write failed", &error, 1)); |
| 319 | gpr_mu_unlock(&h->mu); |
| 320 | security_handshaker_unref(exec_ctx, h); |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 321 | return; |
| 322 | } |
Julien Boeuf | 87047d7 | 2015-08-21 14:30:33 -0700 | [diff] [blame] | 323 | /* We may be done. */ |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 324 | if (tsi_handshaker_is_in_progress(h->handshaker)) { |
Mark D. Roth | 95fcb58 | 2016-11-29 11:29:19 -0800 | [diff] [blame] | 325 | grpc_endpoint_read(exec_ctx, h->args->endpoint, h->args->read_buffer, |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 326 | &h->on_handshake_data_received_from_peer); |
| 327 | } else { |
Mark D. Roth | 3beb6c5 | 2016-11-29 11:25:12 -0800 | [diff] [blame] | 328 | error = check_peer_locked(exec_ctx, h); |
| 329 | if (error != GRPC_ERROR_NONE) { |
Mark D. Roth | 75d0c42 | 2016-11-30 11:40:57 -0800 | [diff] [blame] | 330 | security_handshake_failed_locked(exec_ctx, h, error); |
Mark D. Roth | 3beb6c5 | 2016-11-29 11:25:12 -0800 | [diff] [blame] | 331 | gpr_mu_unlock(&h->mu); |
Mark D. Roth | 75d0c42 | 2016-11-30 11:40:57 -0800 | [diff] [blame] | 332 | security_handshaker_unref(exec_ctx, h); |
Mark D. Roth | 3beb6c5 | 2016-11-29 11:25:12 -0800 | [diff] [blame] | 333 | return; |
| 334 | } |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 335 | } |
Mark D. Roth | 3beb6c5 | 2016-11-29 11:25:12 -0800 | [diff] [blame] | 336 | gpr_mu_unlock(&h->mu); |
Julien Boeuf | 87047d7 | 2015-08-21 14:30:33 -0700 | [diff] [blame] | 337 | } |
| 338 | |
Mark D. Roth | 963be37 | 2016-11-16 14:17:06 -0800 | [diff] [blame] | 339 | // |
| 340 | // public handshaker API |
| 341 | // |
| 342 | |
Mark D. Roth | a561785 | 2016-12-01 08:48:22 -0800 | [diff] [blame] | 343 | static void security_handshaker_destroy(grpc_exec_ctx *exec_ctx, |
| 344 | grpc_handshaker *handshaker) { |
| 345 | security_handshaker *h = (security_handshaker *)handshaker; |
Mark D. Roth | 75d0c42 | 2016-11-30 11:40:57 -0800 | [diff] [blame] | 346 | security_handshaker_unref(exec_ctx, h); |
Craig Tiller | ae13494 | 2016-06-14 08:31:48 -0700 | [diff] [blame] | 347 | } |
| 348 | |
Mark D. Roth | a561785 | 2016-12-01 08:48:22 -0800 | [diff] [blame] | 349 | static void security_handshaker_shutdown(grpc_exec_ctx *exec_ctx, |
Craig Tiller | cda759d | 2017-01-27 11:37:37 -0800 | [diff] [blame] | 350 | grpc_handshaker *handshaker, |
| 351 | grpc_error *why) { |
Mark D. Roth | a561785 | 2016-12-01 08:48:22 -0800 | [diff] [blame] | 352 | security_handshaker *h = (security_handshaker *)handshaker; |
Mark D. Roth | 3beb6c5 | 2016-11-29 11:25:12 -0800 | [diff] [blame] | 353 | gpr_mu_lock(&h->mu); |
Mark D. Roth | 75d0c42 | 2016-11-30 11:40:57 -0800 | [diff] [blame] | 354 | if (!h->shutdown) { |
| 355 | h->shutdown = true; |
Craig Tiller | cda759d | 2017-01-27 11:37:37 -0800 | [diff] [blame] | 356 | grpc_endpoint_shutdown(exec_ctx, h->args->endpoint, GRPC_ERROR_REF(why)); |
Craig Tiller | 397bff3 | 2016-12-06 15:05:59 -0800 | [diff] [blame] | 357 | cleanup_args_for_failure_locked(exec_ctx, h); |
Mark D. Roth | 183a59f | 2016-11-17 11:10:00 -0800 | [diff] [blame] | 358 | } |
Mark D. Roth | 3beb6c5 | 2016-11-29 11:25:12 -0800 | [diff] [blame] | 359 | gpr_mu_unlock(&h->mu); |
Craig Tiller | cda759d | 2017-01-27 11:37:37 -0800 | [diff] [blame] | 360 | GRPC_ERROR_UNREF(why); |
Mark D. Roth | 963be37 | 2016-11-16 14:17:06 -0800 | [diff] [blame] | 361 | } |
| 362 | |
Mark D. Roth | a561785 | 2016-12-01 08:48:22 -0800 | [diff] [blame] | 363 | static void security_handshaker_do_handshake(grpc_exec_ctx *exec_ctx, |
| 364 | grpc_handshaker *handshaker, |
| 365 | grpc_tcp_server_acceptor *acceptor, |
| 366 | grpc_closure *on_handshake_done, |
| 367 | grpc_handshaker_args *args) { |
| 368 | security_handshaker *h = (security_handshaker *)handshaker; |
Mark D. Roth | 3beb6c5 | 2016-11-29 11:25:12 -0800 | [diff] [blame] | 369 | gpr_mu_lock(&h->mu); |
Mark D. Roth | 963be37 | 2016-11-16 14:17:06 -0800 | [diff] [blame] | 370 | h->args = args; |
| 371 | h->on_handshake_done = on_handshake_done; |
Mark D. Roth | 963be37 | 2016-11-16 14:17:06 -0800 | [diff] [blame] | 372 | gpr_ref(&h->refs); |
Mark D. Roth | a561785 | 2016-12-01 08:48:22 -0800 | [diff] [blame] | 373 | grpc_error *error = send_handshake_bytes_to_peer_locked(exec_ctx, h); |
Mark D. Roth | 3beb6c5 | 2016-11-29 11:25:12 -0800 | [diff] [blame] | 374 | if (error != GRPC_ERROR_NONE) { |
Mark D. Roth | 75d0c42 | 2016-11-30 11:40:57 -0800 | [diff] [blame] | 375 | security_handshake_failed_locked(exec_ctx, h, error); |
Mark D. Roth | 3beb6c5 | 2016-11-29 11:25:12 -0800 | [diff] [blame] | 376 | gpr_mu_unlock(&h->mu); |
Mark D. Roth | 75d0c42 | 2016-11-30 11:40:57 -0800 | [diff] [blame] | 377 | security_handshaker_unref(exec_ctx, h); |
Mark D. Roth | 3beb6c5 | 2016-11-29 11:25:12 -0800 | [diff] [blame] | 378 | return; |
| 379 | } |
| 380 | gpr_mu_unlock(&h->mu); |
Mark D. Roth | 963be37 | 2016-11-16 14:17:06 -0800 | [diff] [blame] | 381 | } |
| 382 | |
| 383 | static const grpc_handshaker_vtable security_handshaker_vtable = { |
Mark D. Roth | a561785 | 2016-12-01 08:48:22 -0800 | [diff] [blame] | 384 | security_handshaker_destroy, security_handshaker_shutdown, |
| 385 | security_handshaker_do_handshake}; |
Mark D. Roth | 963be37 | 2016-11-16 14:17:06 -0800 | [diff] [blame] | 386 | |
Mark D. Roth | a561785 | 2016-12-01 08:48:22 -0800 | [diff] [blame] | 387 | static grpc_handshaker *security_handshaker_create( |
Craig Tiller | 449c64b | 2016-06-13 16:26:50 -0700 | [diff] [blame] | 388 | grpc_exec_ctx *exec_ctx, tsi_handshaker *handshaker, |
Mark D. Roth | 963be37 | 2016-11-16 14:17:06 -0800 | [diff] [blame] | 389 | grpc_security_connector *connector) { |
Craig Tiller | 6f41788 | 2017-02-16 14:09:39 -0800 | [diff] [blame] | 390 | security_handshaker *h = gpr_zalloc(sizeof(security_handshaker)); |
Mark D. Roth | 963be37 | 2016-11-16 14:17:06 -0800 | [diff] [blame] | 391 | grpc_handshaker_init(&security_handshaker_vtable, &h->base); |
Julien Boeuf | db5282b | 2015-08-21 15:23:52 -0700 | [diff] [blame] | 392 | h->handshaker = handshaker; |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 393 | h->connector = GRPC_SECURITY_CONNECTOR_REF(connector, "handshake"); |
Mark D. Roth | 3beb6c5 | 2016-11-29 11:25:12 -0800 | [diff] [blame] | 394 | gpr_mu_init(&h->mu); |
| 395 | gpr_ref_init(&h->refs, 1); |
Julien Boeuf | 87047d7 | 2015-08-21 14:30:33 -0700 | [diff] [blame] | 396 | h->handshake_buffer_size = GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE; |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 397 | h->handshake_buffer = gpr_malloc(h->handshake_buffer_size); |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 398 | grpc_closure_init(&h->on_handshake_data_sent_to_peer, |
Craig Tiller | 91031da | 2016-12-28 15:44:25 -0800 | [diff] [blame] | 399 | on_handshake_data_sent_to_peer, h, |
| 400 | grpc_schedule_on_exec_ctx); |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 401 | grpc_closure_init(&h->on_handshake_data_received_from_peer, |
Craig Tiller | 91031da | 2016-12-28 15:44:25 -0800 | [diff] [blame] | 402 | on_handshake_data_received_from_peer, h, |
| 403 | grpc_schedule_on_exec_ctx); |
| 404 | grpc_closure_init(&h->on_peer_checked, on_peer_checked, h, |
| 405 | grpc_schedule_on_exec_ctx); |
Craig Tiller | d41a4a7 | 2016-10-26 16:16:06 -0700 | [diff] [blame] | 406 | grpc_slice_buffer_init(&h->left_overs); |
| 407 | grpc_slice_buffer_init(&h->outgoing); |
Mark D. Roth | 963be37 | 2016-11-16 14:17:06 -0800 | [diff] [blame] | 408 | return &h->base; |
Julien Boeuf | 87047d7 | 2015-08-21 14:30:33 -0700 | [diff] [blame] | 409 | } |
yang-g | 5e72a35 | 2015-11-20 09:49:36 -0800 | [diff] [blame] | 410 | |
Mark D. Roth | 963be37 | 2016-11-16 14:17:06 -0800 | [diff] [blame] | 411 | // |
| 412 | // fail_handshaker |
| 413 | // |
| 414 | |
Mark D. Roth | a561785 | 2016-12-01 08:48:22 -0800 | [diff] [blame] | 415 | static void fail_handshaker_destroy(grpc_exec_ctx *exec_ctx, |
| 416 | grpc_handshaker *handshaker) { |
Mark D. Roth | 963be37 | 2016-11-16 14:17:06 -0800 | [diff] [blame] | 417 | gpr_free(handshaker); |
| 418 | } |
| 419 | |
Mark D. Roth | a561785 | 2016-12-01 08:48:22 -0800 | [diff] [blame] | 420 | static void fail_handshaker_shutdown(grpc_exec_ctx *exec_ctx, |
Craig Tiller | cda759d | 2017-01-27 11:37:37 -0800 | [diff] [blame] | 421 | grpc_handshaker *handshaker, |
| 422 | grpc_error *why) { |
| 423 | GRPC_ERROR_UNREF(why); |
| 424 | } |
Mark D. Roth | 963be37 | 2016-11-16 14:17:06 -0800 | [diff] [blame] | 425 | |
Mark D. Roth | a561785 | 2016-12-01 08:48:22 -0800 | [diff] [blame] | 426 | static void fail_handshaker_do_handshake(grpc_exec_ctx *exec_ctx, |
| 427 | grpc_handshaker *handshaker, |
| 428 | grpc_tcp_server_acceptor *acceptor, |
| 429 | grpc_closure *on_handshake_done, |
| 430 | grpc_handshaker_args *args) { |
Craig Tiller | 91031da | 2016-12-28 15:44:25 -0800 | [diff] [blame] | 431 | grpc_closure_sched(exec_ctx, on_handshake_done, |
| 432 | GRPC_ERROR_CREATE("Failed to create security handshaker")); |
Mark D. Roth | 963be37 | 2016-11-16 14:17:06 -0800 | [diff] [blame] | 433 | } |
| 434 | |
| 435 | static const grpc_handshaker_vtable fail_handshaker_vtable = { |
Mark D. Roth | a561785 | 2016-12-01 08:48:22 -0800 | [diff] [blame] | 436 | fail_handshaker_destroy, fail_handshaker_shutdown, |
| 437 | fail_handshaker_do_handshake}; |
Mark D. Roth | 963be37 | 2016-11-16 14:17:06 -0800 | [diff] [blame] | 438 | |
Mark D. Roth | a561785 | 2016-12-01 08:48:22 -0800 | [diff] [blame] | 439 | static grpc_handshaker *fail_handshaker_create() { |
| 440 | grpc_handshaker *h = gpr_malloc(sizeof(*h)); |
Mark D. Roth | 963be37 | 2016-11-16 14:17:06 -0800 | [diff] [blame] | 441 | grpc_handshaker_init(&fail_handshaker_vtable, h); |
| 442 | return h; |
| 443 | } |
| 444 | |
| 445 | // |
Mark D. Roth | 1f0f23c | 2017-01-06 13:07:19 -0800 | [diff] [blame] | 446 | // handshaker factories |
| 447 | // |
| 448 | |
| 449 | static void client_handshaker_factory_add_handshakers( |
| 450 | grpc_exec_ctx *exec_ctx, grpc_handshaker_factory *handshaker_factory, |
| 451 | const grpc_channel_args *args, grpc_handshake_manager *handshake_mgr) { |
| 452 | grpc_channel_security_connector *security_connector = |
David Garcia Quintas | 0129150 | 2017-02-07 13:26:41 -0800 | [diff] [blame] | 453 | (grpc_channel_security_connector *)grpc_security_connector_find_in_args( |
Mark D. Roth | 1f0f23c | 2017-01-06 13:07:19 -0800 | [diff] [blame] | 454 | args); |
| 455 | grpc_channel_security_connector_add_handshakers(exec_ctx, security_connector, |
| 456 | handshake_mgr); |
| 457 | } |
| 458 | |
| 459 | static void server_handshaker_factory_add_handshakers( |
| 460 | grpc_exec_ctx *exec_ctx, grpc_handshaker_factory *hf, |
| 461 | const grpc_channel_args *args, grpc_handshake_manager *handshake_mgr) { |
| 462 | grpc_server_security_connector *security_connector = |
David Garcia Quintas | 0129150 | 2017-02-07 13:26:41 -0800 | [diff] [blame] | 463 | (grpc_server_security_connector *)grpc_security_connector_find_in_args( |
Mark D. Roth | 1f0f23c | 2017-01-06 13:07:19 -0800 | [diff] [blame] | 464 | args); |
| 465 | grpc_server_security_connector_add_handshakers(exec_ctx, security_connector, |
| 466 | handshake_mgr); |
| 467 | } |
| 468 | |
| 469 | static void handshaker_factory_destroy( |
| 470 | grpc_exec_ctx *exec_ctx, grpc_handshaker_factory *handshaker_factory) {} |
| 471 | |
| 472 | static const grpc_handshaker_factory_vtable client_handshaker_factory_vtable = { |
| 473 | client_handshaker_factory_add_handshakers, handshaker_factory_destroy}; |
| 474 | |
| 475 | static grpc_handshaker_factory client_handshaker_factory = { |
| 476 | &client_handshaker_factory_vtable}; |
| 477 | |
| 478 | static const grpc_handshaker_factory_vtable server_handshaker_factory_vtable = { |
| 479 | server_handshaker_factory_add_handshakers, handshaker_factory_destroy}; |
| 480 | |
| 481 | static grpc_handshaker_factory server_handshaker_factory = { |
| 482 | &server_handshaker_factory_vtable}; |
| 483 | |
| 484 | // |
Mark D. Roth | 963be37 | 2016-11-16 14:17:06 -0800 | [diff] [blame] | 485 | // exported functions |
| 486 | // |
| 487 | |
Mark D. Roth | d095340 | 2016-12-07 07:56:48 -0800 | [diff] [blame] | 488 | grpc_handshaker *grpc_security_handshaker_create( |
| 489 | grpc_exec_ctx *exec_ctx, tsi_handshaker *handshaker, |
| 490 | grpc_security_connector *connector) { |
| 491 | // If no TSI handshaker was created, return a handshaker that always fails. |
| 492 | // Otherwise, return a real security handshaker. |
Mark D. Roth | 963be37 | 2016-11-16 14:17:06 -0800 | [diff] [blame] | 493 | if (handshaker == NULL) { |
Mark D. Roth | d095340 | 2016-12-07 07:56:48 -0800 | [diff] [blame] | 494 | return fail_handshaker_create(); |
Mark D. Roth | 963be37 | 2016-11-16 14:17:06 -0800 | [diff] [blame] | 495 | } else { |
Mark D. Roth | d095340 | 2016-12-07 07:56:48 -0800 | [diff] [blame] | 496 | return security_handshaker_create(exec_ctx, handshaker, connector); |
Mark D. Roth | 963be37 | 2016-11-16 14:17:06 -0800 | [diff] [blame] | 497 | } |
yang-g | 5e72a35 | 2015-11-20 09:49:36 -0800 | [diff] [blame] | 498 | } |
Mark D. Roth | 1f0f23c | 2017-01-06 13:07:19 -0800 | [diff] [blame] | 499 | |
| 500 | void grpc_security_register_handshaker_factories() { |
| 501 | grpc_handshaker_factory_register(false /* at_start */, HANDSHAKER_CLIENT, |
| 502 | &client_handshaker_factory); |
| 503 | grpc_handshaker_factory_register(false /* at_start */, HANDSHAKER_SERVER, |
| 504 | &server_handshaker_factory); |
| 505 | } |