1 /*
2  * Copyright (c) 2023-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 "file_access_service_stub.h"
17 
18 #include <memory>
19 #include <string>
20 
21 #include "access_token.h"
22 #include "accesstoken_kit.h"
23 #include "file_access_framework_errno.h"
24 #include "file_access_service_ipc_interface_code.h"
25 #include "hilog_wrapper.h"
26 #include "hitrace_meter.h"
27 #include "ipc_object_stub.h"
28 #include "ipc_skeleton.h"
29 #include "user_access_tracer.h"
30 #include "message_parcel.h"
31 #include "uri.h"
32 
33 namespace OHOS {
34 namespace FileAccessFwk {
35 namespace {
36     const std::string FILE_ACCESS_PERMISSION = "ohos.permission.FILE_ACCESS_MANAGER";
37 }
FileAccessServiceStub()38 FileAccessServiceStub::FileAccessServiceStub()
39 {
40     stubFuncMap_[static_cast<uint32_t>(FileAccessServiceInterfaceCode::CMD_REGISTER_NOTIFY)] =
41         &FileAccessServiceStub::CmdRegisterNotify;
42     stubFuncMap_[static_cast<uint32_t>(FileAccessServiceInterfaceCode::CMD_UNREGISTER_NOTIFY)] =
43         &FileAccessServiceStub::CmdUnregisterNotify;
44     stubFuncMap_[static_cast<uint32_t>(FileAccessServiceInterfaceCode::CMD_ONCHANGE)] =
45         &FileAccessServiceStub::CmdOnChange;
46     stubFuncMap_[static_cast<uint32_t>(FileAccessServiceInterfaceCode::CMD_CONNECT_FILE_EXT_ABILITY)] =
47         &FileAccessServiceStub::CmdConnectFileExtAbility;
48     stubFuncMap_[static_cast<uint32_t>(FileAccessServiceInterfaceCode::CMD_DISCONNECT_FILE_EXT_ABILITY)] =
49         &FileAccessServiceStub::CmdDisConnectFileExtAbility;
50 }
51 
~FileAccessServiceStub()52 FileAccessServiceStub::~FileAccessServiceStub()
53 {
54     stubFuncMap_.clear();
55 }
56 
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)57 int32_t FileAccessServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply,
58     MessageOption &option)
59 {
60     UserAccessTracer trace;
61     trace.Start("OnRemoteRequest");
62     std::u16string descriptor = FileAccessServiceStub::GetDescriptor();
63     std::u16string remoteDescriptor = data.ReadInterfaceToken();
64     if (descriptor != remoteDescriptor) {
65         return ERR_INVALID_STATE;
66     }
67 
68     if (!CheckCallingPermission(FILE_ACCESS_PERMISSION)) {
69         HILOG_ERROR("permission error");
70         return E_PERMISSION;
71     }
72 
73     const auto &itFunc = stubFuncMap_.find(code);
74     if (itFunc != stubFuncMap_.end()) {
75         return (this->*(itFunc->second))(data, reply);
76     }
77     return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
78 }
79 
CmdOnChange(MessageParcel & data,MessageParcel & reply)80 ErrCode FileAccessServiceStub::CmdOnChange(MessageParcel &data, MessageParcel &reply)
81 {
82     UserAccessTracer trace;
83     trace.Start("CmdOnChange");
84     std::shared_ptr<Uri> uri(data.ReadParcelable<Uri>());
85     if (uri == nullptr) {
86         HILOG_ERROR("UnregisterNotify uri is nullptr");
87         return E_IPCS;
88     }
89 
90     NotifyType notifyType = static_cast<NotifyType>(data.ReadInt32());
91     int ret = OnChange(*uri, notifyType);
92     if (!reply.WriteInt32(ret)) {
93         HILOG_ERROR("Parameter OnChange fail to WriteInt32 ret");
94         return E_IPCS;
95     }
96 
97     return ret;
98 }
99 
CmdRegisterNotify(MessageParcel & data,MessageParcel & reply)100 ErrCode FileAccessServiceStub::CmdRegisterNotify(MessageParcel &data, MessageParcel &reply)
101 {
102     UserAccessTracer trace;
103     trace.Start("CmdRegisterNotify");
104     std::shared_ptr<Uri> uri(data.ReadParcelable<Uri>());
105     if (uri == nullptr) {
106         HILOG_ERROR("RegisterNotify uri is nullptr");
107         return E_IPCS;
108     }
109 
110     sptr<IRemoteObject> obj = data.ReadRemoteObject();
111     if (obj == nullptr) {
112         HILOG_INFO("get remote obj fail.");
113         return E_IPCS;
114     }
115 
116     sptr<IFileAccessObserver> observer = iface_cast<IFileAccessObserver>(obj);
117     if (observer == nullptr) {
118         HILOG_INFO("get observer fail");
119         return E_IPCS;
120     }
121 
122     bool notifyForDescendants = data.ReadBool();
123     auto connectExtensionInfo = std::make_shared<ConnectExtensionInfo>();
124     if (!connectExtensionInfo->ReadFromParcel(data)) {
125         HILOG_ERROR("fail to read info");
126         return E_IPCS;
127     }
128     int ret = RegisterNotify(*uri, notifyForDescendants, observer, connectExtensionInfo);
129     if (!reply.WriteInt32(ret)) {
130         HILOG_ERROR("Parameter RegisterNotify fail to WriteInt32 ret");
131         return E_IPCS;
132     }
133     return ERR_OK;
134 }
135 
CmdUnregisterNotify(MessageParcel & data,MessageParcel & reply)136 ErrCode FileAccessServiceStub::CmdUnregisterNotify(MessageParcel &data, MessageParcel &reply)
137 {
138     UserAccessTracer trace;
139     trace.Start("CmdUnregisterNotify");
140     std::shared_ptr<Uri> uri(data.ReadParcelable<Uri>());
141     if (uri == nullptr) {
142         HILOG_ERROR("UnregisterNotify uri is nullptr");
143         return E_IPCS;
144     }
145 
146     bool observerNotNull = data.ReadBool();
147     int ret = E_IPCS;
148     if (observerNotNull) {
149         sptr<IRemoteObject> obj = data.ReadRemoteObject();
150         if (obj == nullptr) {
151             HILOG_ERROR("get remote obj fail.");
152             return E_IPCS;
153         }
154 
155         sptr<IFileAccessObserver> observer = iface_cast<IFileAccessObserver>(obj);
156         if (observer == nullptr) {
157             HILOG_ERROR("get observer fail");
158             return E_IPCS;
159         }
160 
161         auto connectExtensionInfo = std::make_shared<ConnectExtensionInfo>();
162         if (!connectExtensionInfo->ReadFromParcel(data)) {
163             HILOG_ERROR("fail to read info");
164             return E_IPCS;
165         }
166         ret = UnregisterNotify(*uri, observer, connectExtensionInfo);
167     } else {
168         auto connectExtensionInfo = std::make_shared<ConnectExtensionInfo>();
169         if (!connectExtensionInfo->ReadFromParcel(data)) {
170             HILOG_ERROR("fail to read info");
171             return E_IPCS;
172         }
173         ret = CleanAllNotify(*uri, connectExtensionInfo);
174     }
175 
176     if (!reply.WriteInt32(ret)) {
177         HILOG_ERROR("Parameter UnregisterNotify fail to WriteInt32 ret");
178         return E_IPCS;
179     }
180     return ERR_OK;
181 }
182 
CheckCallingPermission(const std::string & permission)183 bool FileAccessServiceStub::CheckCallingPermission(const std::string &permission)
184 {
185     UserAccessTracer trace;
186     trace.Start("CheckCallingPermission");
187     Security::AccessToken::AccessTokenID tokenCaller = IPCSkeleton::GetCallingTokenID();
188     int res = Security::AccessToken::AccessTokenKit::VerifyAccessToken(tokenCaller, permission);
189     if (res != Security::AccessToken::PermissionState::PERMISSION_GRANTED) {
190         HILOG_ERROR("FileAccessExtStub::CheckCallingPermission have no fileAccess permission");
191         return false;
192     }
193 
194     return true;
195 }
196 
CmdConnectFileExtAbility(MessageParcel & data,MessageParcel & reply)197 ErrCode FileAccessServiceStub::CmdConnectFileExtAbility(MessageParcel &data, MessageParcel &reply)
198 {
199     UserAccessTracer trace;
200     trace.Start("CmdConnectFileExtAbility");
201     std::shared_ptr<AAFwk::Want> wantPtr(data.ReadParcelable<AAFwk::Want>());
202     if (wantPtr == nullptr) {
203         return E_IPCS;
204     }
205     AAFwk::Want want = AAFwk::Want(*wantPtr);
206 
207     sptr<AAFwk::IAbilityConnection> connection = iface_cast<AAFwk::IAbilityConnection>(data.ReadRemoteObject());
208     if (!connection) {
209         HILOG_ERROR("fail to read connection");
210         return E_IPCS;
211     }
212 
213     int ret = ConnectFileExtAbility(want, connection);
214     if (!reply.WriteInt32(ret)) {
215         HILOG_ERROR("fail to CmdConnectFileExtAbility");
216         return E_IPCS;
217     }
218 
219     return ERR_OK;
220 }
221 
222 
CmdDisConnectFileExtAbility(MessageParcel & data,MessageParcel & reply)223 ErrCode FileAccessServiceStub::CmdDisConnectFileExtAbility(MessageParcel &data, MessageParcel &reply)
224 {
225     UserAccessTracer trace;
226     trace.Start("CmdDisConnectFileExtAbility");
227     sptr<AAFwk::IAbilityConnection> connection = iface_cast<AAFwk::IAbilityConnection>(data.ReadRemoteObject());
228     if (!connection) {
229         HILOG_ERROR("fail to read connection");
230         return E_IPCS;
231     }
232 
233     int ret = DisConnectFileExtAbility(connection);
234     if (!reply.WriteInt32(ret)) {
235         HILOG_ERROR("fail to CmdDisConnectFileExtAbility");
236         return E_IPCS;
237     }
238 
239     return ERR_OK;
240 }
241 
CmdGetExensionProxy(MessageParcel & data,MessageParcel & reply)242 ErrCode FileAccessServiceStub::CmdGetExensionProxy(MessageParcel &data, MessageParcel &reply)
243 {
244     UserAccessTracer trace;
245     trace.Start("CmdGetExensionProxy");
246     std::shared_ptr<ConnectExtensionInfo> connectExtensionInfo = std::make_shared<ConnectExtensionInfo>();
247     if (!connectExtensionInfo->ReadFromParcel(data)) {
248         HILOG_ERROR("fail to read info");
249         return E_IPCS;
250     }
251 
252     sptr<IFileAccessExtBase> extensionProxy;
253     int ret = GetExtensionProxy(connectExtensionInfo, extensionProxy);
254     if (!reply.WriteInt32(ret) || extensionProxy == nullptr) {
255         HILOG_ERROR("fail to GetExtensionProxy");
256         return E_IPCS;
257     }
258     if (!reply.WriteRemoteObject(extensionProxy->AsObject())) {
259         HILOG_ERROR("fail to WriteRemoteObject observer");
260         return E_IPCS;
261     }
262     return ERR_OK;
263 }
264 } // namespace FileAccessFwk
265 } // namespace OHOS
266