• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020 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 "bundle_daemon.h"
17 
18 #include <string>
19 
20 #include "bundle_daemon_log.h"
21 #include "liteipc_adapter.h"
22 #include "ohos_errno.h"
23 #include "ohos_init.h"
24 #include "samgr_lite.h"
25 #include "serializer.h"
26 
27 namespace OHOS {
28 namespace {
29 constexpr int STACK_SIZE = 0x800;
30 constexpr int QUEUE_SIZE = 20;
31 constexpr pid_t BMS_UID = 7;
32 }
33 constexpr InvokeFunc BundleDaemon::invokeFuncs[];
34 
35 static BundleDaemonFeature g_defaultApi = {
36     SERVER_IPROXY_IMPL_BEGIN,
37     .Invoke = BundleDaemon::Invoke,
38     IPROXY_END,
39 };
40 
Init()41 static void Init()
42 {
43     SamgrLite *samgrLite = SAMGR_GetInstance();
44     if (samgrLite == nullptr) {
45         PRINTE("BundleDaemon", "get samgr is nullptr");
46         return;
47     }
48     BOOL result = samgrLite->RegisterService(&BundleDaemon::GetInstance());
49     if (!result) {
50         PRINTE("BundleDaemon", "register bundle_daemon service fail");
51         return;
52     }
53     result = samgrLite->RegisterDefaultFeatureApi(BDS_SERVICE, GET_IUNKNOWN(g_defaultApi));
54     PRINTE("BundleDaemon", "register default feature api %{public}s", result ? "success" : "fail");
55 }
56 SYSEX_SERVICE_INIT(Init);
57 
BundleDaemon()58 BundleDaemon::BundleDaemon()
59 {
60     this->Service::GetName = BundleDaemon::GetServiceName;
61     this->Service::Initialize = BundleDaemon::ServiceInitialize;
62     this->Service::MessageHandle = BundleDaemon::ServiceMessageHandle;
63     this->Service::GetTaskConfig = BundleDaemon::GetServiceTaskConfig;
64 }
65 
66 
~BundleDaemon()67 BundleDaemon::~BundleDaemon()
68 {
69     delete bundleMsClient_;
70 }
71 
GetServiceName(Service * service)72 const char *BundleDaemon::GetServiceName(Service *service)
73 {
74     (void)service;
75     return BDS_SERVICE;
76 }
77 
ServiceInitialize(Service * service,Identity identity)78 BOOL BundleDaemon::ServiceInitialize(Service *service, Identity identity)
79 {
80     if (service == nullptr) {
81         return FALSE;
82     }
83     BundleDaemon *bundleDaemon = static_cast<BundleDaemon *>(service);
84     bundleDaemon->identity_ = identity;
85     return TRUE;
86 }
87 
GetServiceTaskConfig(Service * service)88 TaskConfig BundleDaemon::GetServiceTaskConfig(Service *service)
89 {
90     TaskConfig config = {LEVEL_HIGH, PRI_NORMAL, STACK_SIZE, QUEUE_SIZE, SINGLE_TASK};
91     return config;
92 }
93 
ServiceMessageHandle(Service * service,Request * request)94 BOOL BundleDaemon::ServiceMessageHandle(Service *service, Request *request)
95 {
96     if (request == nullptr) {
97         return FALSE;
98     }
99     return TRUE;
100 }
101 
Invoke(IServerProxy * iProxy,int32_t funcId,void * origin,IpcIo * req,IpcIo * reply)102 int32_t BundleDaemon::Invoke(IServerProxy *iProxy, int32_t funcId, void *origin, IpcIo *req, IpcIo *reply)
103 {
104     PRINTI("BundleDaemon", "bundle_daemon invoke start %{public}d", funcId);
105     if (origin == nullptr || req == nullptr) {
106         PRINTE("BundleDaemon", "invalid param");
107         return EC_INVALID;
108     }
109     // check permission
110     pid_t uid = GetCallingUid(origin);
111     if (uid != BMS_UID) {
112         PRINTE("BundleDaemon", "permission denied");
113         return EC_PERMISSION;
114     }
115     if (funcId == REGISTER_CALLBACK) {
116 #ifdef __LINUX__
117         return EC_SUCCESS;
118 #else
119         return RegisterCallbackInvoke(req);
120 #endif
121     }
122 #ifndef __LINUX__
123     if (BundleDaemon::GetInstance().bundleMsClient_ == nullptr) {
124         PRINTE("BundleDaemon", "bundleMsClient is nullptr");
125         return EC_NOINIT;
126     }
127 #endif
128     int32_t ret = EC_COMMU;
129     if (funcId >= EXTRACT_HAP && funcId < BDS_CMD_END) {
130         ret = (BundleDaemon::invokeFuncs[funcId])(req);
131     }
132 #ifdef __LINUX__
133     IpcIoPushInt32(reply, ret);
134     return ret;
135 #else
136     return BundleDaemon::GetInstance().bundleMsClient_->SendReply(ret);
137 #endif
138 }
139 
RegisterCallbackInvoke(IpcIo * req)140 int32_t BundleDaemon::RegisterCallbackInvoke(IpcIo *req)
141 {
142     SvcIdentity *svcIdentity = IpcIoPopSvc(req);
143     if (svcIdentity == nullptr) {
144         return EC_INVALID;
145     }
146     BundleDaemon::GetInstance().bundleMsClient_ = new BundleMsClient(*svcIdentity);
147     return BundleDaemon::GetInstance().bundleMsClient_->SendReply(EC_SUCCESS);
148 }
149 
ObtainStringFromIpc(IpcIo * req,std::string & firstStr,std::string & secondStr)150 static int32_t ObtainStringFromIpc(IpcIo *req, std::string &firstStr, std::string &secondStr)
151 {
152 #ifdef __LINUX__
153     size_t length = 0;
154     std::string innerStr = reinterpret_cast<char *>(IpcIoPopString(req, &length));
155 #else
156     BuffPtr *buff = IpcIoPopDataBuff(req);
157     if (buff == nullptr || buff->buffSz == 0) {
158         return EC_INVALID;
159     }
160     std::string innerStr = reinterpret_cast<char *>(buff->buff);
161 #endif
162     uint32_t len = IpcIoPopUint16(req);
163     if (innerStr.length() <= len) {
164 #ifndef __LINUX__
165         FreeBuffer(nullptr, buff->buff);
166 #endif
167         return EC_INVALID;
168     }
169     firstStr = innerStr.substr(0, len);
170     secondStr = innerStr.substr(len);
171 #ifndef __LINUX__
172     FreeBuffer(nullptr, buff->buff);
173 #endif
174     return EC_SUCCESS;
175 }
176 
ExtractHapInvoke(IpcIo * req)177 int32_t BundleDaemon::ExtractHapInvoke(IpcIo *req)
178 {
179     std::string hapPath = "";
180     std::string codePath = "";
181     int32_t ret = ObtainStringFromIpc(req, hapPath, codePath);
182     if (ret != EC_SUCCESS) {
183         return ret;
184     }
185     return BundleDaemon::GetInstance().handler_.ExtractHap(hapPath.c_str(), codePath.c_str());
186 }
187 
RenameFileInvoke(IpcIo * req)188 int32_t BundleDaemon::RenameFileInvoke(IpcIo *req)
189 {
190     std::string oldFile = "";
191     std::string newFile = "";
192     int32_t ret = ObtainStringFromIpc(req, oldFile, newFile);
193     if (ret != EC_SUCCESS) {
194         return ret;
195     }
196     return BundleDaemon::GetInstance().handler_.RenameFile(oldFile.c_str(), newFile.c_str());
197 }
198 
CreatePermissionInvoke(IpcIo * req)199 int32_t BundleDaemon::CreatePermissionInvoke(IpcIo *req)
200 {
201     return BundleDaemon::GetInstance().handler_.CreatePermissionDir();
202 }
203 
CreateDataDirectoryInvoke(IpcIo * req)204 int32_t BundleDaemon::CreateDataDirectoryInvoke(IpcIo *req)
205 {
206     size_t len = 0;
207     const char *dataPath = reinterpret_cast<char *>(IpcIoPopString(req, &len));
208     if (dataPath == nullptr || len == 0) {
209         return EC_INVALID;
210     }
211     int32_t uid = IpcIoPopInt32(req);
212     int32_t gid = IpcIoPopInt32(req);
213     bool isChown = IpcIoPopBool(req);
214 
215     return BundleDaemon::GetInstance().handler_.CreateDataDirectory(dataPath, uid, gid, isChown);
216 }
217 
StoreContentToFileInvoke(IpcIo * req)218 int32_t BundleDaemon::StoreContentToFileInvoke(IpcIo *req)
219 {
220     size_t len = 0;
221     const char *path = reinterpret_cast<char *>(IpcIoPopString(req, &len));
222     if (path == nullptr || len == 0) {
223         return EC_INVALID;
224     }
225 #ifdef __LINUX__
226     size_t buffLen = 0;
227     const char *buff = reinterpret_cast<char *>(IpcIoPopString(req, &buffLen));
228     if (buff == nullptr || buffLen == 0) {
229         return EC_INVALID;
230     }
231     int32_t ret = BundleDaemon::GetInstance().handler_.StoreContentToFile(path, buff, buffLen);
232 #else
233     BuffPtr *buffPtr = IpcIoPopDataBuff(req);
234     if (buffPtr == nullptr || buffPtr->buffSz == 0) {
235         return EC_INVALID;
236     }
237     char *buff = reinterpret_cast<char *>(buffPtr->buff);
238     if (buff == nullptr) {
239         return EC_INVALID;
240     }
241 
242     int32_t ret = BundleDaemon::GetInstance().handler_.StoreContentToFile(path, buff, buffPtr->buffSz);
243     FreeBuffer(nullptr, buffPtr->buff);
244 #endif
245     return ret;
246 }
247 
MoveFileInvoke(IpcIo * req)248 int32_t BundleDaemon::MoveFileInvoke(IpcIo *req)
249 {
250     size_t len = 0;
251     const char *oldFile = reinterpret_cast<char *>(IpcIoPopString(req, &len));
252     if (oldFile == nullptr || len == 0) {
253         return EC_INVALID;
254     }
255     const char *newFile = reinterpret_cast<char *>(IpcIoPopString(req, &len));
256     if (newFile == nullptr || len == 0) {
257         return EC_INVALID;
258     }
259     return BundleDaemon::GetInstance().handler_.MoveFile(oldFile, newFile);
260 }
261 
RemoveFileInvoke(IpcIo * req)262 int32_t BundleDaemon::RemoveFileInvoke(IpcIo *req)
263 {
264     size_t len = 0;
265     const char *path = reinterpret_cast<char *>(IpcIoPopString(req, &len));
266     if (path == nullptr || len == 0) {
267         return EC_INVALID;
268     }
269     return BundleDaemon::GetInstance().handler_.RemoveFile(path);
270 }
271 
RemoveInstallDirectoryInvoke(IpcIo * req)272 int32_t BundleDaemon::RemoveInstallDirectoryInvoke(IpcIo *req)
273 {
274     std::string codePath = "";
275     std::string dataPath = "";
276     int32_t ret = ObtainStringFromIpc(req, codePath, dataPath);
277     if (ret != EC_SUCCESS) {
278         return ret;
279     }
280     bool keepData = IpcIoPopBool(req);
281     return BundleDaemon::GetInstance().handler_.RemoveInstallDirectory(codePath.c_str(), dataPath.c_str(), keepData);
282 }
283 } // OHOS
284