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 "want_utils.h"
17 #include "element_name_utils.h"
18
19 #include <securec.h>
20 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
21 #include <string>
22 #include "ipc_skeleton.h"
23 #endif
24
25 #include "log.h"
26 #include "utils.h"
27
28 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
29 using UriKeyType = enum {
30 BEGIN,
31 DEVICE,
32 BUNDLE,
33 ABILITY,
34 END,
35 };
36
37 using UriProperties = struct {
38 const char *key; /* key of uri property */
39 uint8_t keyLen; /* key length of uri property */
40 UriKeyType type; /* key type of uri property */
41 };
42
43 const static UriProperties URI_PROPERTIES[] = {
44 { "#Want", 5, BEGIN },
45 { "device=", 7, DEVICE },
46 { "bundle=", 7, BUNDLE },
47 { "ability=", 8, ABILITY },
48 { "end", 3, END },
49 };
50
51 constexpr static char URI_SEPARATOR = ';';
52 constexpr static int VALUE_NULL = 0;
53 constexpr static int VALUE_OBJECT = 1;
54 constexpr static int DATA_LENGTH = 2048;
55 #endif
56
57 constexpr uint8_t INT_VALUE_TYPE = 6;
58 constexpr uint8_t STRING_VALUE_TYPE = 13;
59 constexpr uint8_t KEY_VALUE_PAIR_TYPE = 97;
60
ClearWant(Want * want)61 void ClearWant(Want *want)
62 {
63 if (want == nullptr) {
64 return;
65 }
66
67 ClearElement(want->element);
68 AdapterFree(want->element);
69 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
70 AdapterFree(want->sid);
71 #endif
72 AdapterFree(want->appPath);
73 AdapterFree(want->data);
74 #ifndef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
75 AdapterFree(want->actions);
76 AdapterFree(want->entities);
77 #endif
78 }
79
SetWantElement(Want * want,ElementName element)80 bool SetWantElement(Want *want, ElementName element)
81 {
82 if (want == nullptr) {
83 return false;
84 }
85
86 ClearElement(want->element);
87 AdapterFree(want->element);
88 want->element = reinterpret_cast<ElementName *>(AdapterMalloc(sizeof(ElementName)));
89 if (want->element == nullptr) {
90 return false;
91 }
92 want->element->deviceId = OHOS::Utils::Strdup(element.deviceId);
93 want->element->bundleName = OHOS::Utils::Strdup(element.bundleName);
94 want->element->abilityName = OHOS::Utils::Strdup(element.abilityName);
95 return true;
96 }
97
EncapTlv(uint8_t type,uint8_t length,const void * value,uint8_t valueLen)98 Tlv *EncapTlv(uint8_t type, uint8_t length, const void *value, uint8_t valueLen)
99 {
100 void *entity = nullptr;
101
102 // Tlv header can only has 2 bytes.
103 uint8_t totalLen = valueLen + 2;
104 entity = AdapterMalloc(totalLen);
105 if (entity == nullptr) {
106 return nullptr;
107 }
108
109 if (memcpy_s((unsigned char *)entity, totalLen, &type, 1) != 0 ||
110 memcpy_s((unsigned char *)entity + 1, totalLen - 1, &length, 1) != 0 ||
111 memcpy_s((unsigned char *)entity + 2, valueLen, value, valueLen) != 0) {
112 AdapterFree(entity);
113 return nullptr;
114 }
115
116 Tlv *newTlv = reinterpret_cast<Tlv *>(AdapterMalloc(sizeof(Tlv)));
117 if (newTlv == nullptr) {
118 AdapterFree(entity);
119 return nullptr;
120 }
121
122 newTlv->type = type;
123 newTlv->entity = entity;
124 newTlv->totalLen = totalLen;
125 return newTlv;
126 }
127
FreeTlvStruct(Tlv * tlv)128 void FreeTlvStruct(Tlv *tlv)
129 {
130 AdapterFree(tlv->entity);
131 AdapterFree(tlv);
132 }
133
CombineKeyValueTlv(Tlv * keyTlv,Tlv * valueTlv)134 Tlv *CombineKeyValueTlv(Tlv *keyTlv, Tlv *valueTlv)
135 {
136 uint8_t newTlvValueLen = keyTlv->totalLen + valueTlv->totalLen;
137 void *newTlvValue = AdapterMalloc(newTlvValueLen);
138 if (newTlvValue == nullptr) {
139 return nullptr;
140 }
141 if (memcpy_s((unsigned char *)newTlvValue, keyTlv->totalLen, keyTlv->entity, keyTlv->totalLen) != 0 ||
142 memcpy_s((unsigned char *)newTlvValue + keyTlv->totalLen, valueTlv->totalLen,
143 valueTlv->entity, valueTlv->totalLen) != 0) {
144 AdapterFree(newTlvValue);
145 return nullptr;
146 }
147
148 Tlv *newTlv = EncapTlv(KEY_VALUE_PAIR_TYPE, newTlvValueLen, newTlvValue, newTlvValueLen);
149 AdapterFree(newTlvValue);
150 return newTlv;
151 }
152
UpdateWantData(Want * want,Tlv * tlv)153 bool UpdateWantData(Want *want, Tlv *tlv)
154 {
155 bool result = false;
156 if (want->data != nullptr) {
157 void *newWantData = AdapterMalloc(tlv->totalLen + want->dataLength);
158 if (newWantData == nullptr) {
159 return result;
160 }
161 if (memcpy_s(newWantData, want->dataLength, want->data, want->dataLength) != 0 ||
162 memcpy_s((unsigned char*)newWantData + want->dataLength, tlv->totalLen, tlv->entity, tlv->totalLen) != 0) {
163 AdapterFree(newWantData);
164 return result;
165 }
166 SetWantData(want, newWantData, tlv->totalLen + want->dataLength);
167 AdapterFree(newWantData);
168 result = true;
169 } else {
170 SetWantData(want, tlv->entity, tlv->totalLen);
171 result = true;
172 }
173 return result;
174 }
175
SetIntParam(Want * want,const char * key,uint8_t keyLen,int32_t value)176 bool SetIntParam(Want *want, const char *key, uint8_t keyLen, int32_t value)
177 {
178 bool result = false;
179 if (keyLen <= 0) {
180 return result;
181 }
182
183 Tlv *keyTlv = EncapTlv(STRING_VALUE_TYPE, keyLen, (void *)key, keyLen);
184 if (keyTlv == nullptr) {
185 return result;
186 }
187 if (value < 0) {
188 HILOG_ERROR(HILOG_MODULE_APP, "SetIntParam value should be positive");
189 FreeTlvStruct(keyTlv);
190 return result;
191 }
192 int intBufferNumber = 4;
193 unsigned char intBuffer[4] = {0};
194 for (int i = 0; i < intBufferNumber; i++) {
195 intBuffer[i] = value >> (8 * (3- i));
196 }
197 Tlv *valueTlv = EncapTlv(INT_VALUE_TYPE, sizeof(int), (void *)intBuffer, sizeof(int));
198 if (valueTlv == nullptr) {
199 FreeTlvStruct(keyTlv);
200 return result;
201 }
202 Tlv *newTlv = CombineKeyValueTlv(keyTlv, valueTlv);
203 FreeTlvStruct(keyTlv);
204 FreeTlvStruct(valueTlv);
205 if (newTlv == nullptr) {
206 return result;
207 }
208 if (UpdateWantData(want, newTlv)) {
209 result = true;
210 }
211 AdapterFree(newTlv);
212 return result;
213 }
214
SetStrParam(Want * want,const char * key,uint8_t keyLen,const char * value,uint8_t valueLen)215 bool SetStrParam(Want *want, const char *key, uint8_t keyLen, const char *value, uint8_t valueLen)
216 {
217 bool result = false;
218 if (keyLen <= 0 || valueLen <= 0) {
219 return result;
220 }
221
222 Tlv *keyTlv = EncapTlv(STRING_VALUE_TYPE, keyLen, (void *)key, keyLen);
223 if (keyTlv == nullptr) {
224 return result;
225 }
226
227 Tlv *valueTlv = EncapTlv(STRING_VALUE_TYPE, valueLen, (void *)value, valueLen);
228 if (valueTlv == nullptr) {
229 FreeTlvStruct(keyTlv);
230 return result;
231 }
232 Tlv *newTlv = CombineKeyValueTlv(keyTlv, valueTlv);
233 FreeTlvStruct(keyTlv);
234 FreeTlvStruct(valueTlv);
235 if (newTlv == nullptr) {
236 return result;
237 }
238 if (UpdateWantData(want, newTlv)) {
239 result = true;
240 }
241 AdapterFree(newTlv);
242 return result;
243 }
244
245 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
SetWantSvcIdentity(Want * want,SvcIdentity sid)246 bool SetWantSvcIdentity(Want *want, SvcIdentity sid)
247 {
248 if (want == nullptr) {
249 return false;
250 }
251
252 AdapterFree(want->sid);
253 want->sid = reinterpret_cast<SvcIdentity *>(AdapterMalloc(sizeof(SvcIdentity)));
254 if (want->sid == nullptr) {
255 return false;
256 }
257 if (memcpy_s(want->sid, sizeof(SvcIdentity), &sid, sizeof(SvcIdentity)) != EOK) {
258 AdapterFree(want->sid);
259 return false;
260 }
261
262 return true;
263 }
264 #endif
265
SetWantData(Want * want,const void * data,uint16_t dataLength)266 bool SetWantData(Want *want, const void *data, uint16_t dataLength)
267 {
268 if (want == nullptr) {
269 return false;
270 }
271
272 AdapterFree(want->data);
273 want->data = OHOS::Utils::Memdup(data, dataLength);
274 if (want->data == nullptr) {
275 want->dataLength = 0;
276 return false;
277 }
278
279 want->dataLength = dataLength;
280 return true;
281 }
282
283 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
SerializeWant(IpcIo * io,const Want * want)284 bool SerializeWant(IpcIo *io, const Want *want)
285 {
286 if ((io == nullptr) || (want == nullptr) || (want->dataLength > DATA_LENGTH)) {
287 return false;
288 }
289
290 if (want->element == nullptr) {
291 WriteInt32(io, VALUE_NULL);
292 } else {
293 WriteInt32(io, VALUE_OBJECT);
294 if (!SerializeElement(io, want->element)) {
295 return false;
296 }
297 }
298 WriteInt32(io, want->dataLength);
299 if (want->dataLength > 0) {
300 WriteBuffer(io, want->data, want->dataLength);
301 }
302 if (want->sid == nullptr) {
303 WriteInt32(io, VALUE_NULL);
304 } else {
305 WriteInt32(io, VALUE_OBJECT);
306 bool ret = WriteRemoteObject(io, want->sid);
307 if (!ret) {
308 return false;
309 }
310 }
311
312 return true;
313 }
314
DeserializeWant(Want * want,IpcIo * io)315 bool DeserializeWant(Want *want, IpcIo *io)
316 {
317 if ((want == nullptr) || (io == nullptr)) {
318 return false;
319 }
320
321 int ret = 0;
322 ReadInt32(io, &ret);
323 if (ret == VALUE_OBJECT) {
324 want->element = reinterpret_cast<ElementName *>(AdapterMalloc(sizeof(ElementName)));
325 if (want->element == nullptr ||
326 memset_s(want->element, sizeof(ElementName), 0, sizeof(ElementName)) != EOK ||
327 !DeserializeElement(want->element, io)) {
328 AdapterFree(want->element);
329 return false;
330 }
331 }
332 uint32_t size = 0;
333 ReadUint32(io, &size);
334 if (size > 0) {
335 void *data = (void*)ReadBuffer(io, (size_t)size);
336 if (!SetWantData(want, data, size)) {
337 ClearWant(want);
338 return false;
339 }
340 }
341 ReadInt32(io, &ret);
342 if (ret == VALUE_OBJECT) {
343 SvcIdentity svc;
344 bool ret = ReadRemoteObject(io, &svc);
345 if (!ret || !SetWantSvcIdentity(want, svc)) {
346 ClearWant(want);
347 return false;
348 }
349 }
350
351 return true;
352 }
353
WantParseUri(const char * uri)354 Want *WantParseUri(const char *uri)
355 {
356 if (uri == nullptr) {
357 return nullptr;
358 }
359 char *parseUri = OHOS::Utils::Strdup(uri);
360 if (parseUri == nullptr) {
361 return nullptr;
362 }
363 ElementName element = { nullptr, nullptr, nullptr };
364 char *beginIndex = parseUri;
365 for (auto property : URI_PROPERTIES) {
366 if (strstr(beginIndex, property.key) != beginIndex) {
367 AdapterFree(parseUri);
368 return nullptr;
369 }
370 if (property.type == END) {
371 break;
372 }
373 char *endIndex = strchr(beginIndex, URI_SEPARATOR);
374 if ((endIndex == nullptr) || (endIndex <= beginIndex)) {
375 AdapterFree(parseUri);
376 return nullptr;
377 }
378 *endIndex = '\0';
379 beginIndex += property.keyLen;
380 switch (property.type) {
381 case DEVICE: {
382 SetElementDeviceID(&element, beginIndex);
383 break;
384 }
385 case BUNDLE: {
386 SetElementBundleName(&element, beginIndex);
387 break;
388 }
389 case ABILITY: {
390 SetElementAbilityName(&element, beginIndex);
391 break;
392 }
393 default: {
394 break;
395 }
396 }
397 beginIndex = endIndex + 1;
398 }
399 AdapterFree(parseUri);
400 Want *want = new Want();
401 if ((memset_s(want, sizeof(Want), 0, sizeof(Want)) != EOK) || !SetWantElement(want, element)) {
402 ClearElement(&element);
403 delete want;
404 return nullptr;
405 }
406 ClearElement(&element);
407 return want;
408 }
409
WantToUri(Want want)410 const char *WantToUri(Want want)
411 {
412 std::string uriString;
413
414 for (auto property : URI_PROPERTIES) {
415 uriString += property.key;
416 switch (property.type) {
417 case BEGIN: {
418 uriString += URI_SEPARATOR;
419 break;
420 }
421 case DEVICE: {
422 if ((want.element != nullptr) && (want.element->deviceId != nullptr)) {
423 uriString += want.element->deviceId;
424 }
425 uriString += URI_SEPARATOR;
426 break;
427 }
428 case BUNDLE: {
429 if ((want.element != nullptr) && (want.element->bundleName != nullptr)) {
430 uriString += want.element->bundleName;
431 }
432 uriString += URI_SEPARATOR;
433 break;
434 }
435 case ABILITY: {
436 if ((want.element != nullptr) && (want.element->abilityName != nullptr)) {
437 uriString += want.element->abilityName;
438 }
439 uriString += URI_SEPARATOR;
440 break;
441 }
442 default: {
443 break;
444 }
445 }
446 }
447
448 uint16_t len = uriString.size();
449 char *uri = reinterpret_cast<char *>(AdapterMalloc(len + 1));
450 if (uri == nullptr) {
451 return nullptr;
452 }
453 if (strncpy_s(uri, len + 1, uriString.c_str(), len) < 0) {
454 AdapterFree(uri);
455 return nullptr;
456 }
457
458 return uri;
459 }
460 #endif
461