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