1 /*
2  * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
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 
16 #include "distributed_ability_manager_stub.h"
17 
18 #include <iosfwd>
19 #include <memory>
20 #include <string>
21 #include <utility>
22 
23 #include "accesstoken_kit.h"
24 #include "base/continuationmgr_log.h"
25 #include "base/parcel_helper.h"
26 #include "continuation_extra_params.h"
27 #include "device_connect_status.h"
28 #include "iremote_object.h"
29 #include "ipc_skeleton.h"
30 
31 namespace OHOS {
32 namespace DistributedSchedule {
33 using namespace OHOS::Security;
34 namespace {
35 const std::string TAG = "ContinuationManagerStub";
36 const std::string PERMISSION_DISTRIBUTED_DATASYNC = "ohos.permission.DISTRIBUTED_DATASYNC";
37 }
38 
DistributedAbilityManagerStub()39 DistributedAbilityManagerStub::DistributedAbilityManagerStub()
40 {
41     funcsMap_[static_cast<uint32_t>(IDAbilityManagerInterfaceCode::REGISTER)] =
42         &DistributedAbilityManagerStub::RegisterInner;
43     funcsMap_[static_cast<uint32_t>(IDAbilityManagerInterfaceCode::UNREGISTER)] =
44         &DistributedAbilityManagerStub::UnregisterInner;
45     funcsMap_[static_cast<uint32_t>(IDAbilityManagerInterfaceCode::REGISTER_DEVICE_SELECTION_CALLBACK)] =
46         &DistributedAbilityManagerStub::RegisterDeviceSelectionCallbackInner;
47     funcsMap_[static_cast<uint32_t>(IDAbilityManagerInterfaceCode::UNREGISTER_DEVICE_SELECTION_CALLBACK)] =
48         &DistributedAbilityManagerStub::UnregisterDeviceSelectionCallbackInner;
49     funcsMap_[static_cast<uint32_t>(IDAbilityManagerInterfaceCode::UPDATE_CONNECT_STATUS)] =
50         &DistributedAbilityManagerStub::UpdateConnectStatusInner;
51     funcsMap_[static_cast<uint32_t>(IDAbilityManagerInterfaceCode::START_DEVICE_MANAGER)] =
52         &DistributedAbilityManagerStub::StartDeviceManagerInner;
53 }
54 
~DistributedAbilityManagerStub()55 DistributedAbilityManagerStub::~DistributedAbilityManagerStub()
56 {
57     funcsMap_.clear();
58 }
59 
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)60 int32_t DistributedAbilityManagerStub::OnRemoteRequest(uint32_t code, MessageParcel& data,
61     MessageParcel& reply, MessageOption& option)
62 {
63     HILOGI("code = %{public}u", code);
64     auto iter = funcsMap_.find(code);
65     if (iter != funcsMap_.end()) {
66         auto func = iter->second;
67         if (!EnforceInterfaceToken(data)) {
68             HILOGE("interface token check failed!");
69             return DMS_PERMISSION_DENIED;
70         }
71         uint32_t accessToken = IPCSkeleton::GetCallingTokenID();
72         if (!VerifyPermission(accessToken, PERMISSION_DISTRIBUTED_DATASYNC)) {
73             HILOGE("DISTRIBUTED_DATASYNC permission check failed!");
74             return DMS_PERMISSION_DENIED;
75         }
76         if (func != nullptr) {
77             return (this->*func)(data, reply);
78         } else {
79             HILOGE("func is nullptr");
80             return ERR_NULL_OBJECT;
81         }
82     }
83     return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
84 }
85 
EnforceInterfaceToken(MessageParcel & data)86 bool DistributedAbilityManagerStub::EnforceInterfaceToken(MessageParcel& data)
87 {
88     std::u16string interfaceToken = data.ReadInterfaceToken();
89     return interfaceToken == IDistributedAbilityManager::GetDescriptor();
90 }
91 
RegisterInner(MessageParcel & data,MessageParcel & reply)92 int32_t DistributedAbilityManagerStub::RegisterInner(MessageParcel& data, MessageParcel& reply)
93 {
94     int32_t flag = VALUE_NULL;
95     PARCEL_READ_HELPER(data, Int32, flag);
96     int32_t token = -1;
97     ContinuationExtraParams* continuationExtraParams = nullptr;
98     if (flag == VALUE_OBJECT) {
99         continuationExtraParams = data.ReadParcelable<ContinuationExtraParams>();
100         if (continuationExtraParams == nullptr) {
101             HILOGE("ContinuationExtraParams readParcelable failed!");
102             return ERR_NULL_OBJECT;
103         }
104     }
105     std::shared_ptr<ContinuationExtraParams> continuationExtraParamsPtr(continuationExtraParams);
106     int32_t result = Register(continuationExtraParamsPtr, token);
107     HILOGI("result = %{public}d", result);
108     PARCEL_WRITE_HELPER(reply, Int32, result);
109     PARCEL_WRITE_HELPER(reply, Int32, token);
110     return ERR_NONE;
111 }
112 
UnregisterInner(MessageParcel & data,MessageParcel & reply)113 int32_t DistributedAbilityManagerStub::UnregisterInner(MessageParcel& data, MessageParcel& reply)
114 {
115     int32_t token = -1;
116     PARCEL_READ_HELPER(data, Int32, token);
117     int32_t result = Unregister(token);
118     HILOGI("result = %{public}d", result);
119     PARCEL_WRITE_HELPER(reply, Int32, result);
120     return ERR_NONE;
121 }
122 
RegisterDeviceSelectionCallbackInner(MessageParcel & data,MessageParcel & reply)123 int32_t DistributedAbilityManagerStub::RegisterDeviceSelectionCallbackInner(MessageParcel& data, MessageParcel& reply)
124 {
125     int32_t token = -1;
126     PARCEL_READ_HELPER(data, Int32, token);
127     std::string cbType;
128     PARCEL_READ_HELPER(data, String, cbType);
129     if (cbType.empty()) {
130         HILOGE("cbType unmarshalling failed!");
131         return ERR_NULL_OBJECT;
132     }
133     sptr<IRemoteObject> notifier = data.ReadRemoteObject();
134     if (notifier == nullptr) {
135         HILOGE("notifier unmarshalling failed!");
136         return ERR_NULL_OBJECT;
137     }
138     int32_t result = RegisterDeviceSelectionCallback(token, cbType, notifier);
139     HILOGI("result = %{public}d", result);
140     PARCEL_WRITE_HELPER(reply, Int32, result);
141     return ERR_NONE;
142 }
143 
UnregisterDeviceSelectionCallbackInner(MessageParcel & data,MessageParcel & reply)144 int32_t DistributedAbilityManagerStub::UnregisterDeviceSelectionCallbackInner(MessageParcel& data,
145     MessageParcel& reply)
146 {
147     int32_t token = -1;
148     PARCEL_READ_HELPER(data, Int32, token);
149     std::string cbType;
150     PARCEL_READ_HELPER(data, String, cbType);
151     if (cbType.empty()) {
152         HILOGE("cbType unmarshalling failed!");
153         return ERR_NULL_OBJECT;
154     }
155     int32_t result = UnregisterDeviceSelectionCallback(token, cbType);
156     HILOGI("result = %{public}d", result);
157     PARCEL_WRITE_HELPER(reply, Int32, result);
158     return ERR_NONE;
159 }
160 
UpdateConnectStatusInner(MessageParcel & data,MessageParcel & reply)161 int32_t DistributedAbilityManagerStub::UpdateConnectStatusInner(MessageParcel& data, MessageParcel& reply)
162 {
163     int32_t token = -1;
164     PARCEL_READ_HELPER(data, Int32, token);
165     std::string deviceId;
166     PARCEL_READ_HELPER(data, String, deviceId);
167     DeviceConnectStatus deviceConnectStatus = static_cast<DeviceConnectStatus>(data.ReadInt32());
168     int32_t result = UpdateConnectStatus(token, deviceId, deviceConnectStatus);
169     HILOGI("result = %{public}d", result);
170     PARCEL_WRITE_HELPER(reply, Int32, result);
171     return ERR_NONE;
172 }
173 
StartDeviceManagerInner(MessageParcel & data,MessageParcel & reply)174 int32_t DistributedAbilityManagerStub::StartDeviceManagerInner(MessageParcel& data, MessageParcel& reply)
175 {
176     int32_t token = -1;
177     PARCEL_READ_HELPER(data, Int32, token);
178     int32_t flag = VALUE_NULL;
179     PARCEL_READ_HELPER(data, Int32, flag);
180     ContinuationExtraParams* continuationExtraParams = nullptr;
181     if (flag == VALUE_OBJECT) {
182         continuationExtraParams = data.ReadParcelable<ContinuationExtraParams>();
183         if (continuationExtraParams == nullptr) {
184             HILOGE("ContinuationExtraParams readParcelable failed!");
185             return ERR_NULL_OBJECT;
186         }
187     }
188     std::shared_ptr<ContinuationExtraParams> continuationExtraParamsPtr(continuationExtraParams);
189     int32_t result = StartDeviceManager(token, continuationExtraParamsPtr);
190     HILOGI("result = %{public}d", result);
191     PARCEL_WRITE_HELPER(reply, Int32, result);
192     return ERR_NONE;
193 }
194 
VerifyPermission(uint32_t accessToken,const std::string & permissionName) const195 bool DistributedAbilityManagerStub::VerifyPermission(uint32_t accessToken, const std::string& permissionName) const
196 {
197     int32_t result = AccessToken::AccessTokenKit::VerifyAccessToken(accessToken, permissionName);
198     if (result == AccessToken::PermissionState::PERMISSION_DENIED) {
199         HILOGE("permission denied, permissionName:%{public}s", permissionName.c_str());
200         return false;
201     }
202     HILOGD("permission matched.");
203     return true;
204 }
205 
206 } // namespace DistributedSchedule
207 } // namespace OHOS