1 /*
2 * Copyright (c) 2021-2024 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 "ipc/daemon_stub.h"
17
18 #include "dfs_error.h"
19 #include "dfsu_access_token_helper.h"
20 #include "dm_device_info.h"
21 #include "ipc/distributed_file_daemon_ipc_interface_code.h"
22 #include "ipc_skeleton.h"
23 #include "utils_log.h"
24
25 namespace OHOS {
26 namespace Storage {
27 namespace DistributedFile {
28 using namespace OHOS::FileManagement;
29 const int32_t UID = 1009;
30 const int32_t DATA_UID = 3012;
DaemonStub()31 DaemonStub::DaemonStub()
32 {
33 opToInterfaceMap_[static_cast<uint32_t>(DistributedFileDaemonInterfaceCode::DISTRIBUTED_FILE_OPEN_P2P_CONNECTION)] =
34 &DaemonStub::HandleOpenP2PConnection;
35 opToInterfaceMap_[static_cast<uint32_t>(
36 DistributedFileDaemonInterfaceCode::DISTRIBUTED_FILE_CLOSE_P2P_CONNECTION)] =
37 &DaemonStub::HandleCloseP2PConnection;
38 opToInterfaceMap_[static_cast<uint32_t>(
39 DistributedFileDaemonInterfaceCode::DISTRIBUTED_FILE_OPEN_P2P_CONNECTION_EX)] =
40 &DaemonStub::HandleOpenP2PConnectionEx;
41 opToInterfaceMap_[static_cast<uint32_t>(
42 DistributedFileDaemonInterfaceCode::DISTRIBUTED_FILE_CLOSE_P2P_CONNECTION_EX)] =
43 &DaemonStub::HandleCloseP2PConnectionEx;
44 opToInterfaceMap_[static_cast<uint32_t>(DistributedFileDaemonInterfaceCode::DISTRIBUTED_FILE_PREPARE_SESSION)] =
45 &DaemonStub::HandlePrepareSession;
46 opToInterfaceMap_[static_cast<uint32_t>(DistributedFileDaemonInterfaceCode::DISTRIBUTED_FILE_CANCEL_COPY_TASK)] =
47 &DaemonStub::HandleCancelCopyTask;
48 opToInterfaceMap_[static_cast<uint32_t>(DistributedFileDaemonInterfaceCode::DISTRIBUTED_FILE_REQUEST_SEND_FILE)] =
49 &DaemonStub::HandleRequestSendFile;
50 opToInterfaceMap_[static_cast<uint32_t>(
51 DistributedFileDaemonInterfaceCode::DISTRIBUTED_FILE_GET_REMOTE_COPY_INFO)] =
52 &DaemonStub::HandleGetRemoteCopyInfo;
53 opToInterfaceMap_[static_cast<uint32_t>(
54 DistributedFileDaemonInterfaceCode::DISTRIBUTED_FILE_REGISTER_ASSET_CALLBACK)] =
55 &DaemonStub::HandleRegisterRecvCallback;
56 opToInterfaceMap_[static_cast<uint32_t>(
57 DistributedFileDaemonInterfaceCode::DISTRIBUTED_FILE_UN_REGISTER_ASSET_CALLBACK)] =
58 &DaemonStub::HandleUnRegisterRecvCallback;
59 opToInterfaceMap_[static_cast<uint32_t>(
60 DistributedFileDaemonInterfaceCode::DISTRIBUTED_FILE_PUSH_ASSET)] =
61 &DaemonStub::HandlePushAsset;
62 }
63
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)64 int32_t DaemonStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
65 {
66 if (data.ReadInterfaceToken() != GetDescriptor()) {
67 return DFS_DAEMON_DESCRIPTOR_IS_EMPTY;
68 }
69 switch (code) {
70 case static_cast<uint32_t>(DistributedFileDaemonInterfaceCode::DISTRIBUTED_FILE_OPEN_P2P_CONNECTION):
71 return HandleOpenP2PConnection(data, reply);
72 case static_cast<uint32_t>(DistributedFileDaemonInterfaceCode::DISTRIBUTED_FILE_CLOSE_P2P_CONNECTION):
73 return HandleCloseP2PConnection(data, reply);
74 case static_cast<uint32_t>(DistributedFileDaemonInterfaceCode::DISTRIBUTED_FILE_OPEN_P2P_CONNECTION_EX):
75 return HandleOpenP2PConnectionEx(data, reply);
76 case static_cast<uint32_t>(DistributedFileDaemonInterfaceCode::DISTRIBUTED_FILE_CLOSE_P2P_CONNECTION_EX):
77 return HandleCloseP2PConnectionEx(data, reply);
78 case static_cast<uint32_t>(DistributedFileDaemonInterfaceCode::DISTRIBUTED_FILE_PREPARE_SESSION):
79 return HandlePrepareSession(data, reply);
80 case static_cast<uint32_t>(DistributedFileDaemonInterfaceCode::DISTRIBUTED_FILE_CANCEL_COPY_TASK):
81 return HandleCancelCopyTask(data, reply);
82 case static_cast<uint32_t>(DistributedFileDaemonInterfaceCode::DISTRIBUTED_FILE_REQUEST_SEND_FILE):
83 return HandleRequestSendFile(data, reply);
84 case static_cast<uint32_t>(DistributedFileDaemonInterfaceCode::DISTRIBUTED_FILE_GET_REMOTE_COPY_INFO):
85 return HandleGetRemoteCopyInfo(data, reply);
86 case static_cast<uint32_t>(DistributedFileDaemonInterfaceCode::DISTRIBUTED_FILE_REGISTER_ASSET_CALLBACK):
87 return HandleRegisterRecvCallback(data, reply);
88 case static_cast<uint32_t>(DistributedFileDaemonInterfaceCode::DISTRIBUTED_FILE_UN_REGISTER_ASSET_CALLBACK):
89 return HandleUnRegisterRecvCallback(data, reply);
90 case static_cast<uint32_t>(DistributedFileDaemonInterfaceCode::DISTRIBUTED_FILE_PUSH_ASSET):
91 return HandlePushAsset(data, reply);
92 default:
93 LOGE("Cannot response request %d: unknown tranction", code);
94 return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
95 }
96 }
97
HandleOpenP2PConnection(MessageParcel & data,MessageParcel & reply)98 int32_t DaemonStub::HandleOpenP2PConnection(MessageParcel &data, MessageParcel &reply)
99 {
100 LOGI("Begin OpenP2PConnection");
101 if (!DfsuAccessTokenHelper::CheckCallerPermission(PERM_DISTRIBUTED_DATASYNC)) {
102 LOGE("[HandleOpenP2PConnection] DATASYNC permission denied");
103 return E_PERMISSION_DENIED;
104 }
105 DistributedHardware::DmDeviceInfo deviceInfo;
106 auto ret = strcpy_s(deviceInfo.deviceId, DM_MAX_DEVICE_ID_LEN, data.ReadCString());
107 if (ret != 0) {
108 LOGE("strcpy for source device id failed, ret is %{public}d", ret);
109 return -1;
110 }
111 ret = strcpy_s(deviceInfo.deviceName, DM_MAX_DEVICE_NAME_LEN, data.ReadCString());
112 if (ret != 0) {
113 LOGE("strcpy for source device name failed, ret is %{public}d", ret);
114 return -1;
115 }
116 ret = strcpy_s(deviceInfo.networkId, DM_MAX_DEVICE_ID_LEN, data.ReadCString());
117 if (ret != 0) {
118 LOGE("strcpy for source network id failed, ret is %{public}d", ret);
119 return -1;
120 }
121 deviceInfo.deviceTypeId = data.ReadUint16();
122 deviceInfo.range = static_cast<int32_t>(data.ReadUint32());
123 deviceInfo.authForm = static_cast<DistributedHardware::DmAuthForm>(data.ReadInt32());
124
125 int32_t res = OpenP2PConnection(deviceInfo);
126 reply.WriteInt32(res);
127 LOGI("End OpenP2PConnection, res = %{public}d", res);
128 return res;
129 }
130
HandleCloseP2PConnection(MessageParcel & data,MessageParcel & reply)131 int32_t DaemonStub::HandleCloseP2PConnection(MessageParcel &data, MessageParcel &reply)
132 {
133 LOGI("Begin CloseP2PConnection");
134 if (!DfsuAccessTokenHelper::CheckCallerPermission(PERM_DISTRIBUTED_DATASYNC)) {
135 LOGE("[HandleCloseP2PConnection] DATASYNC permission denied");
136 return E_PERMISSION_DENIED;
137 }
138 DistributedHardware::DmDeviceInfo deviceInfo;
139 auto ret = strcpy_s(deviceInfo.deviceId, DM_MAX_DEVICE_ID_LEN, data.ReadCString());
140 if (ret != 0) {
141 LOGE("strcpy for source device id failed, ret is %{public}d", ret);
142 return -1;
143 }
144 ret = strcpy_s(deviceInfo.deviceName, DM_MAX_DEVICE_NAME_LEN, data.ReadCString());
145 if (ret != 0) {
146 LOGE("strcpy for source device name failed, ret is %{public}d", ret);
147 return -1;
148 }
149 ret = strcpy_s(deviceInfo.networkId, DM_MAX_DEVICE_ID_LEN, data.ReadCString());
150 if (ret != 0) {
151 LOGE("strcpy for source network id failed, ret is %{public}d", ret);
152 return -1;
153 }
154 deviceInfo.deviceTypeId = data.ReadUint16();
155 deviceInfo.range = static_cast<int32_t>(data.ReadUint32());
156 deviceInfo.authForm = static_cast<DistributedHardware::DmAuthForm>(data.ReadInt32());
157
158 int32_t res = CloseP2PConnection(deviceInfo);
159 reply.WriteInt32(res);
160 LOGI("End CloseP2PConnection");
161 return res;
162 }
163
HandleOpenP2PConnectionEx(MessageParcel & data,MessageParcel & reply)164 int32_t DaemonStub::HandleOpenP2PConnectionEx(MessageParcel &data, MessageParcel &reply)
165 {
166 LOGI("DaemonStub::Begin OpenP2PConnectionEx");
167 std::string networkId;
168 if (!data.ReadString(networkId)) {
169 LOGE("read networkId failed");
170 return E_IPC_READ_FAILED;
171 }
172 auto remote = data.ReadRemoteObject();
173 if (remote == nullptr) {
174 LOGE("read remoteObject failed");
175 return E_IPC_READ_FAILED;
176 }
177 auto remoteReverseObj = iface_cast<IFileDfsListener>(remote);
178 if (remoteReverseObj == nullptr) {
179 LOGE("remoteReverseObj is null");
180 return E_INVAL_ARG;
181 }
182 int32_t res = OpenP2PConnectionEx(networkId, remoteReverseObj);
183 reply.WriteInt32(res);
184 LOGI("DaemonStub::End OpenP2PConnection, res = %{public}d.", res);
185 return res;
186 }
187
HandleCloseP2PConnectionEx(MessageParcel & data,MessageParcel & reply)188 int32_t DaemonStub::HandleCloseP2PConnectionEx(MessageParcel &data, MessageParcel &reply)
189 {
190 LOGI("DaemonStub::Begin CloseP2PConnection.");
191 std::string networkId;
192 if (!data.ReadString(networkId)) {
193 LOGE("read networkId failed");
194 return E_IPC_READ_FAILED;
195 }
196
197 int32_t res = CloseP2PConnectionEx(networkId);
198 reply.WriteInt32(res);
199 LOGI("DaemonStub::End CloseP2PConnection");
200 return res;
201 }
202
HandlePrepareSession(MessageParcel & data,MessageParcel & reply)203 int32_t DaemonStub::HandlePrepareSession(MessageParcel &data, MessageParcel &reply)
204 {
205 std::string srcUri;
206 if (!data.ReadString(srcUri)) {
207 LOGE("read srcUri failed");
208 return E_IPC_READ_FAILED;
209 }
210 if (!DfsuAccessTokenHelper::CheckUriPermission(srcUri)) {
211 LOGE("permission verify failed");
212 return E_PERMISSION_DENIED;
213 }
214 std::string dstUri;
215 if (!data.ReadString(dstUri)) {
216 LOGE("read dstUri failed");
217 return E_IPC_READ_FAILED;
218 }
219 std::string srcDeviceId;
220 if (!data.ReadString(srcDeviceId)) {
221 LOGE("read srcDeviceId failed");
222 return E_IPC_READ_FAILED;
223 }
224 auto listener = data.ReadRemoteObject();
225 if (listener == nullptr) {
226 LOGE("read listener failed");
227 return E_IPC_READ_FAILED;
228 }
229 HmdfsInfo info{};
230 if (!data.ReadString(info.copyPath)) {
231 LOGE("read info.copyPath failed");
232 return E_IPC_READ_FAILED;
233 }
234 if (!data.ReadBool(info.dirExistFlag)) {
235 LOGE("read info.dirExistFlag failed");
236 return E_IPC_READ_FAILED;
237 }
238 int32_t res = PrepareSession(srcUri, dstUri, srcDeviceId, listener, info);
239 if (!reply.WriteString(info.sessionName)) {
240 LOGE("Write sessionName failed");
241 return E_IPC_WRITE_FAILED;
242 }
243 reply.WriteInt32(res);
244 LOGD("End PrepareSession, ret = %{public}d.", res);
245 return res;
246 }
247
HandleRequestSendFile(MessageParcel & data,MessageParcel & reply)248 int32_t DaemonStub::HandleRequestSendFile(MessageParcel &data, MessageParcel &reply)
249 {
250 auto uid = IPCSkeleton::GetCallingUid();
251 if (uid != UID) {
252 LOGE("Permission denied, caller is not dfs!");
253 return E_PERMISSION_DENIED;
254 }
255 std::string srcUri;
256 if (!data.ReadString(srcUri)) {
257 LOGE("read srcUri failed");
258 return E_IPC_READ_FAILED;
259 }
260 std::string dstPath;
261 if (!data.ReadString(dstPath)) {
262 LOGE("read dstPath failed");
263 return E_IPC_READ_FAILED;
264 }
265 std::string dstDeviceId;
266 if (!data.ReadString(dstDeviceId)) {
267 LOGE("read remoteDeviceId failed");
268 return E_IPC_READ_FAILED;
269 }
270 std::string sessionName;
271 if (!data.ReadString(sessionName)) {
272 LOGE("read sessionName failed");
273 return E_IPC_READ_FAILED;
274 }
275 auto res = RequestSendFile(srcUri, dstPath, dstDeviceId, sessionName);
276 reply.WriteInt32(res);
277 LOGD("End RequestSendFile, ret = %{public}d.", res);
278 return res;
279 }
280
HandleGetRemoteCopyInfo(MessageParcel & data,MessageParcel & reply)281 int32_t DaemonStub::HandleGetRemoteCopyInfo(MessageParcel &data, MessageParcel &reply)
282 {
283 auto uid = IPCSkeleton::GetCallingUid();
284 if (uid != UID) {
285 LOGE("Permission denied, caller is not dfs!");
286 return E_PERMISSION_DENIED;
287 }
288 std::string srcUri;
289 if (!data.ReadString(srcUri)) {
290 LOGE("read srcUri failed");
291 return E_IPC_READ_FAILED;
292 }
293 bool isFile = false;
294 bool isDir = false;
295 auto res = GetRemoteCopyInfo(srcUri, isFile, isDir);
296 if (res != E_OK) {
297 LOGE("GetRemoteCopyInfo failed");
298 return E_IPC_READ_FAILED;
299 }
300 if (!reply.WriteBool(isFile)) {
301 LOGE("Write isFile failed");
302 return E_IPC_READ_FAILED;
303 }
304 if (!reply.WriteBool(isDir)) {
305 LOGE("Write isDir failed");
306 return E_IPC_READ_FAILED;
307 }
308 if (!reply.WriteInt32(res)) {
309 LOGE("Write res failed");
310 return E_IPC_READ_FAILED;
311 }
312 LOGD("End GetRemoteCopyInfo, ret = %{public}d.", res);
313 return res;
314 }
315
HandleCancelCopyTask(MessageParcel & data,MessageParcel & reply)316 int32_t DaemonStub::HandleCancelCopyTask(MessageParcel &data, MessageParcel &reply)
317 {
318 std::string sessionName;
319 if (!data.ReadString(sessionName)) {
320 LOGE("read sessionName failed");
321 return E_IPC_READ_FAILED;
322 }
323 return CancelCopyTask(sessionName);
324 }
325
HandleRegisterRecvCallback(MessageParcel & data,MessageParcel & reply)326 int32_t DaemonStub::HandleRegisterRecvCallback(MessageParcel &data, MessageParcel &reply)
327 {
328 LOGI("Begin RegisterRecvCallback");
329 auto uid = IPCSkeleton::GetCallingUid();
330 if (uid != DATA_UID) {
331 LOGE("Permission denied, caller is not data!");
332 return E_PERMISSION_DENIED;
333 }
334 if (!DfsuAccessTokenHelper::CheckCallerPermission(PERM_DISTRIBUTED_DATASYNC)) {
335 LOGE("[RegisterRecvCallback] DATASYNC permission denied");
336 return E_PERMISSION_DENIED;
337 }
338 auto object = data.ReadRemoteObject();
339 if (object == nullptr) {
340 LOGE("RegisterRecvCallback failed, object is nullptr.");
341 return E_IPC_READ_FAILED;
342 }
343 auto recvCallback = iface_cast<IAssetRecvCallback>(object);
344 if (recvCallback == nullptr) {
345 LOGE("RegisterRecvCallback failed, Callback is nullptr");
346 return E_INVAL_ARG;
347 }
348 int32_t res = RegisterAssetCallback(recvCallback);
349 if (!reply.WriteInt32(res)) {
350 LOGE("RegisterRecvCallback write res failed, res is %{public}d", res);
351 return E_IPC_READ_FAILED;
352 }
353 return res;
354 }
355
HandleUnRegisterRecvCallback(MessageParcel & data,MessageParcel & reply)356 int32_t DaemonStub::HandleUnRegisterRecvCallback(MessageParcel &data, MessageParcel &reply)
357 {
358 LOGI("Begin UnRegisterRecvCallback");
359 auto uid = IPCSkeleton::GetCallingUid();
360 if (uid != DATA_UID) {
361 LOGE("Permission denied, caller is not data!");
362 return E_PERMISSION_DENIED;
363 }
364 if (!DfsuAccessTokenHelper::CheckCallerPermission(PERM_DISTRIBUTED_DATASYNC)) {
365 LOGE("[UnRegisterRecvCallback] DATASYNC permission denied");
366 return E_PERMISSION_DENIED;
367 }
368 auto object = data.ReadRemoteObject();
369 if (object == nullptr) {
370 LOGE("UnRegisterRecvCallback failed, object is nullptr.");
371 return E_IPC_READ_FAILED;
372 }
373 auto recvCallback = iface_cast<IAssetRecvCallback>(object);
374 if (recvCallback == nullptr) {
375 LOGE("UnRegisterRecvCallback failed, Callback is nullptr");
376 return E_INVAL_ARG;
377 }
378 int32_t res = UnRegisterAssetCallback(recvCallback);
379 if (!reply.WriteInt32(res)) {
380 LOGE("UnRegisterRecvCallback write res failed, res is %{public}d", res);
381 return E_IPC_READ_FAILED;
382 }
383 return res;
384 }
385
HandlePushAsset(MessageParcel & data,MessageParcel & reply)386 int32_t DaemonStub::HandlePushAsset(MessageParcel &data, MessageParcel &reply)
387 {
388 LOGI("Begin PushAsset");
389 auto uid = IPCSkeleton::GetCallingUid();
390 if (uid != DATA_UID) {
391 LOGE("Permission denied, caller is not data!");
392 return E_PERMISSION_DENIED;
393 }
394 if (!DfsuAccessTokenHelper::CheckCallerPermission(PERM_DISTRIBUTED_DATASYNC)) {
395 LOGE("[PushAsset] DATASYNC permission denied");
396 return E_PERMISSION_DENIED;
397 }
398 int32_t userId;
399 if (!data.ReadInt32(userId)) {
400 LOGE("read userId failed");
401 return E_INVAL_ARG;
402 }
403
404 sptr<AssetObj> assetObj = data.ReadParcelable<AssetObj>();
405 if (!assetObj) {
406 LOGE("object of AssetObj is nullptr");
407 return E_INVAL_ARG;
408 }
409
410 auto object = data.ReadRemoteObject();
411 if (object == nullptr) {
412 LOGE("PushAsset failed, object is nullptr.");
413 return E_IPC_READ_FAILED;
414 }
415 auto sendCallback = iface_cast<IAssetSendCallback>(object);
416 if (sendCallback == nullptr) {
417 LOGE("PushAsset failed, Callback is nullptr");
418 return E_INVAL_ARG;
419 }
420
421 int32_t res = PushAsset(userId, assetObj, sendCallback);
422 if (!reply.WriteInt32(res)) {
423 LOGE("PushAsset write res failed, res is %{public}d", res);
424 return E_IPC_READ_FAILED;
425 }
426 return res;
427 }
428 } // namespace DistributedFile
429 } // namespace Storage
430 } // namespace OHOS