1 // Copyright 2021 gRPC authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include <grpc/support/port_platform.h>
16
17 #ifndef GRPC_NO_BINDER
18
19 #include <grpcpp/security/binder_security_policy.h>
20
21 #ifdef GPR_ANDROID
22
23 #include <jni.h>
24 #include <unistd.h>
25
26 #include <grpc/support/log.h>
27
28 #include "src/core/ext/transport/binder/client/jni_utils.h"
29 #include "src/core/lib/gprpp/crash.h"
30
31 #endif
32
33 namespace grpc {
34 namespace experimental {
35 namespace binder {
36
37 UntrustedSecurityPolicy::UntrustedSecurityPolicy() = default;
38
39 UntrustedSecurityPolicy::~UntrustedSecurityPolicy() = default;
40
IsAuthorized(int)41 bool UntrustedSecurityPolicy::IsAuthorized(int) { return true; };
42
43 InternalOnlySecurityPolicy::InternalOnlySecurityPolicy() = default;
44
45 InternalOnlySecurityPolicy::~InternalOnlySecurityPolicy() = default;
46
47 #ifdef GPR_ANDROID
IsAuthorized(int uid)48 bool InternalOnlySecurityPolicy::IsAuthorized(int uid) {
49 return static_cast<uid_t>(uid) == getuid();
50 }
51 #else
IsAuthorized(int)52 bool InternalOnlySecurityPolicy::IsAuthorized(int) { return false; }
53 #endif
54
55 #ifdef GPR_ANDROID
56
57 namespace {
GetEnv(JavaVM * vm)58 JNIEnv* GetEnv(JavaVM* vm) {
59 if (vm == nullptr) return nullptr;
60
61 JNIEnv* result = nullptr;
62 jint attach = vm->AttachCurrentThread(&result, nullptr);
63
64 GPR_ASSERT(JNI_OK == attach);
65 GPR_ASSERT(nullptr != result);
66 return result;
67 }
68 } // namespace
69
SameSignatureSecurityPolicy(JavaVM * jvm,jobject context)70 SameSignatureSecurityPolicy::SameSignatureSecurityPolicy(JavaVM* jvm,
71 jobject context)
72 : jvm_(jvm) {
73 GPR_ASSERT(jvm != nullptr);
74 GPR_ASSERT(context != nullptr);
75
76 JNIEnv* env = GetEnv(jvm_);
77
78 // Make sure the context is still valid when IsAuthorized() is called
79 context_ = env->NewGlobalRef(context);
80 GPR_ASSERT(context_ != nullptr);
81 }
82
~SameSignatureSecurityPolicy()83 SameSignatureSecurityPolicy::~SameSignatureSecurityPolicy() {
84 JNIEnv* env = GetEnv(jvm_);
85 env->DeleteLocalRef(context_);
86 }
87
IsAuthorized(int uid)88 bool SameSignatureSecurityPolicy::IsAuthorized(int uid) {
89 JNIEnv* env = GetEnv(jvm_);
90 bool result = grpc_binder::IsSignatureMatch(env, context_, getuid(), uid);
91 if (result) {
92 gpr_log(GPR_INFO, "uid %d and uid %d passed SameSignature check", getuid(),
93 uid);
94 } else {
95 gpr_log(GPR_ERROR, "uid %d and uid %d failed SameSignature check", getuid(),
96 uid);
97 }
98 return result;
99 }
100
101 #endif
102
103 } // namespace binder
104 } // namespace experimental
105 } // namespace grpc
106 #endif
107