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 <functional>
35 : #include <map>
36 : #include <memory>
37 :
38 : #include "src/cpp/common/secure_auth_context.h"
39 : #include "src/cpp/server/secure_server_credentials.h"
40 :
41 : #include <grpc++/security/auth_metadata_processor.h>
42 :
43 : namespace grpc {
44 :
45 46 : void AuthMetadataProcessorAyncWrapper::Destroy(void* wrapper) {
46 46 : auto* w = reinterpret_cast<AuthMetadataProcessorAyncWrapper*>(wrapper);
47 46 : delete w;
48 46 : }
49 :
50 238 : void AuthMetadataProcessorAyncWrapper::Process(
51 : void* wrapper, grpc_auth_context* context, const grpc_metadata* md,
52 : size_t num_md, grpc_process_auth_metadata_done_cb cb, void* user_data) {
53 238 : auto* w = reinterpret_cast<AuthMetadataProcessorAyncWrapper*>(wrapper);
54 238 : if (!w->processor_) {
55 : // Early exit.
56 234 : cb(user_data, nullptr, 0, nullptr, 0, GRPC_STATUS_OK, nullptr);
57 472 : return;
58 : }
59 4 : if (w->processor_->IsBlocking()) {
60 2 : w->thread_pool_->Add(
61 : std::bind(&AuthMetadataProcessorAyncWrapper::InvokeProcessor, w,
62 2 : context, md, num_md, cb, user_data));
63 : } else {
64 : // invoke directly.
65 2 : w->InvokeProcessor(context, md, num_md, cb, user_data);
66 : }
67 : }
68 :
69 4 : void AuthMetadataProcessorAyncWrapper::InvokeProcessor(
70 : grpc_auth_context* ctx, const grpc_metadata* md, size_t num_md,
71 : grpc_process_auth_metadata_done_cb cb, void* user_data) {
72 4 : AuthMetadataProcessor::InputMetadata metadata;
73 28 : for (size_t i = 0; i < num_md; i++) {
74 : metadata.insert(std::make_pair(
75 24 : md[i].key, grpc::string_ref(md[i].value, md[i].value_length)));
76 : }
77 8 : SecureAuthContext context(ctx, false);
78 8 : AuthMetadataProcessor::OutputMetadata consumed_metadata;
79 8 : AuthMetadataProcessor::OutputMetadata response_metadata;
80 :
81 4 : Status status = processor_->Process(metadata, &context, &consumed_metadata,
82 8 : &response_metadata);
83 :
84 8 : std::vector<grpc_metadata> consumed_md;
85 6 : for (auto it = consumed_metadata.begin(); it != consumed_metadata.end();
86 : ++it) {
87 : grpc_metadata md_entry;
88 2 : md_entry.key = it->first.c_str();
89 2 : md_entry.value = it->second.data();
90 2 : md_entry.value_length = it->second.size();
91 2 : md_entry.flags = 0;
92 2 : consumed_md.push_back(md_entry);
93 : }
94 8 : std::vector<grpc_metadata> response_md;
95 4 : for (auto it = response_metadata.begin(); it != response_metadata.end();
96 : ++it) {
97 : grpc_metadata md_entry;
98 0 : md_entry.key = it->first.c_str();
99 0 : md_entry.value = it->second.data();
100 0 : md_entry.value_length = it->second.size();
101 0 : md_entry.flags = 0;
102 0 : response_md.push_back(md_entry);
103 : }
104 4 : auto consumed_md_data = consumed_md.empty() ? nullptr : &consumed_md[0];
105 4 : auto response_md_data = response_md.empty() ? nullptr : &response_md[0];
106 : cb(user_data, consumed_md_data, consumed_md.size(), response_md_data,
107 4 : response_md.size(), static_cast<grpc_status_code>(status.error_code()),
108 12 : status.error_message().c_str());
109 4 : }
110 :
111 47 : int SecureServerCredentials::AddPortToServer(const grpc::string& addr,
112 : grpc_server* server) {
113 47 : return grpc_server_add_secure_http2_port(server, addr.c_str(), creds_);
114 : }
115 :
116 46 : void SecureServerCredentials::SetAuthMetadataProcessor(
117 : const std::shared_ptr<AuthMetadataProcessor>& processor) {
118 46 : auto* wrapper = new AuthMetadataProcessorAyncWrapper(processor);
119 : grpc_server_credentials_set_auth_metadata_processor(
120 : creds_, {AuthMetadataProcessorAyncWrapper::Process,
121 46 : AuthMetadataProcessorAyncWrapper::Destroy, wrapper});
122 46 : }
123 :
124 47 : std::shared_ptr<ServerCredentials> SslServerCredentials(
125 : const SslServerCredentialsOptions& options) {
126 47 : std::vector<grpc_ssl_pem_key_cert_pair> pem_key_cert_pairs;
127 282 : for (auto key_cert_pair = options.pem_key_cert_pairs.begin();
128 188 : key_cert_pair != options.pem_key_cert_pairs.end(); key_cert_pair++) {
129 47 : grpc_ssl_pem_key_cert_pair p = {key_cert_pair->private_key.c_str(),
130 47 : key_cert_pair->cert_chain.c_str()};
131 47 : pem_key_cert_pairs.push_back(p);
132 : }
133 : grpc_server_credentials* c_creds = grpc_ssl_server_credentials_create(
134 47 : options.pem_root_certs.empty() ? nullptr : options.pem_root_certs.c_str(),
135 47 : pem_key_cert_pairs.empty() ? nullptr : &pem_key_cert_pairs[0],
136 141 : pem_key_cert_pairs.size(), options.force_client_auth, nullptr);
137 : return std::shared_ptr<ServerCredentials>(
138 47 : new SecureServerCredentials(c_creds));
139 : }
140 :
141 : } // namespace grpc
|