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