• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 "sms_wap_push_handler.h"
17 
18 #include <memory>
19 
20 #include "common_event.h"
21 #include "common_event_manager.h"
22 #include "common_event_support.h"
23 #include "mms_msg.h"
24 #include "securec.h"
25 #include "sms_hisysevent.h"
26 #include "sms_persist_helper.h"
27 #include "sms_receive_reliability_handler.h"
28 #include "string_utils.h"
29 #include "telephony_log_wrapper.h"
30 #include "telephony_permission.h"
31 #include "want.h"
32 
33 namespace OHOS {
34 namespace Telephony {
35 using namespace OHOS::EventFwk;
36 static constexpr uint8_t PDU_TYPE_PUSH = 0x06;
37 static constexpr uint8_t PDU_TYPE_CONFIRMED_PUSH = 0x07;
38 static constexpr uint32_t PARAMETER_X_WAP_APPLICATION_ID = 0x2F;
39 static constexpr const char *CONTENT_MIME_TYPE_B_PUSH_CO = "application/vnd.wap.coc";
40 
__anon34bfa1460102() 41 std::shared_ptr<SmsBroadcastSubscriberReceiver> SmsWapPushHandler::g_receiver = []() {
42     MatchingSkills smsSkills;
43     smsSkills.AddEvent(CommonEventSupport::COMMON_EVENT_SMS_WAPPUSH_RECEIVE_COMPLETED);
44     CommonEventSubscribeInfo smsSubscriberInfo(smsSkills);
45     smsSubscriberInfo.SetThreadMode(EventFwk::CommonEventSubscribeInfo::COMMON);
46     return std::make_shared<SmsBroadcastSubscriberReceiver>(smsSubscriberInfo);
47 }();
48 
SmsWapPushHandler(int32_t slotId)49 SmsWapPushHandler::SmsWapPushHandler(int32_t slotId) : slotId_(slotId) {}
50 
~SmsWapPushHandler()51 SmsWapPushHandler::~SmsWapPushHandler() {}
52 
DecodeWapPushPduData(SmsWapPushBuffer & decodeBuffer,uint32_t startPos,uint32_t len)53 bool SmsWapPushHandler::DecodeWapPushPduData(SmsWapPushBuffer &decodeBuffer, uint32_t startPos, uint32_t len)
54 {
55     uint32_t headerLength = len;
56     uint32_t startHeader = startPos;
57 
58     std::unique_ptr<char[]> headerBuffer = nullptr;
59     headerBuffer = decodeBuffer.ReadDataBuffer(startHeader, headerLength);
60     if (headerBuffer == nullptr) {
61         TELEPHONY_LOGE("Read Header Buffer nullptr error");
62         return false;
63     }
64     hexHeaderData_ = StringUtils::StringToHex(static_cast<char *>(headerBuffer.get()), headerLength);
65 
66     uint32_t posData = 0;
67     uint32_t dataLength = 0;
68     if (contentType_.GetContentType() == std::string(CONTENT_MIME_TYPE_B_PUSH_CO)) {
69         dataLength = decodeBuffer.GetSize();
70     } else {
71         dataLength = decodeBuffer.GetSize() - startHeader - headerLength;
72         posData = startHeader + headerLength;
73     }
74     std::unique_ptr<char[]> pduBuffer = nullptr;
75     pduBuffer = decodeBuffer.ReadDataBuffer(posData, dataLength);
76     if (pduBuffer == nullptr) {
77         TELEPHONY_LOGE("Read Pdu Buffer nullptr error");
78         return false;
79     }
80     hexWbXmlData_ = StringUtils::StringToHex(static_cast<char *>(pduBuffer.get()), dataLength);
81     return true;
82 }
83 /*
84  * wap-230-wsp-20010705-a 8.2.4.1 Push and ConfirmedPush
85  */
DecodeWapPushPdu(std::shared_ptr<SmsReceiveIndexer> indexer,std::string & wapPdu)86 bool SmsWapPushHandler::DecodeWapPushPdu(std::shared_ptr<SmsReceiveIndexer> indexer, std::string &wapPdu)
87 {
88     if (indexer == nullptr) {
89         TELEPHONY_LOGE("indexer is nullptr");
90         return false;
91     }
92     SmsWapPushBuffer decodeBuffer;
93     if (!decodeBuffer.WriteRawStringBuffer(wapPdu)) {
94         TELEPHONY_LOGE("Wap push WriteRawStringBuffer fail.");
95         return false;
96     }
97     if (!DecodePushType(decodeBuffer)) {
98         TELEPHONY_LOGE("Wap push DecodePushType fail.");
99         return false;
100     }
101     uint32_t count = 0;
102     uint32_t headerLength = 0;
103     if (!decodeBuffer.DecodeUintvar(headerLength, count)) {
104         TELEPHONY_LOGE("Wap push DecodeUintvar fail.");
105         return false;
106     }
107     int32_t contentTypeLength = 0;
108     uint32_t startHeader = decodeBuffer.GetCurPosition();
109     if (!contentType_.DecodeContentType(decodeBuffer, contentTypeLength)) {
110         TELEPHONY_LOGE("Wap push DecodeContentType fail.");
111         return false;
112     }
113     uint32_t headersLen = 0;
114     uint32_t curentPosition = decodeBuffer.GetCurPosition();
115     if (headerLength + startHeader <= curentPosition) {
116         TELEPHONY_LOGE("Wap push headersLen fail.");
117         return false;
118     }
119     headersLen = headerLength - curentPosition + startHeader;
120     DecodeXWapApplication(decodeBuffer, headersLen);
121 
122     if (!DecodeWapPushPduData(decodeBuffer, startHeader, headerLength)) {
123         TELEPHONY_LOGE("Wap push DecodeWapPushPduData fail.");
124         return false;
125     }
126     if (DeocdeCheckIsBlock(hexWbXmlData_)) {
127         TELEPHONY_LOGI("Wap Push Mms-message Is Blocked Dispatcher.");
128         DeleteWapPush(indexer);
129         SmsHiSysEvent::WriteSmsReceiveFaultEvent(slotId_, SmsMmsMessageType::SMS_SHORT_MESSAGE,
130             SmsMmsErrorCode::SMS_ERROR_ADDRESS_BLOCKED, "The Wap Push address is blocked");
131         return true;
132     }
133     SendWapPushMessageBroadcast(indexer);
134     return true;
135 }
136 
DeleteWapPush(std::shared_ptr<SmsReceiveIndexer> indexer)137 void SmsWapPushHandler::DeleteWapPush(std::shared_ptr<SmsReceiveIndexer> indexer)
138 {
139     auto handler = std::make_shared<SmsReceiveReliabilityHandler>(slotId_);
140     if (handler == nullptr) {
141         TELEPHONY_LOGE("handler is nullptr.");
142         return;
143     }
144     handler->DeleteMessageFormDb(indexer->GetMsgRefId(), indexer->GetDataBaseId());
145 }
146 
147 /*
148  * wap-230-wsp-20010705-a 8.2.4.1 Push and ConfirmedPush
149  * 8.2.4 Push and Confirmed Push Facilities
150  */
DecodePushType(SmsWapPushBuffer & decodeBuffer)151 bool SmsWapPushHandler::DecodePushType(SmsWapPushBuffer &decodeBuffer)
152 {
153     transactionId_ = 0;
154     if (!decodeBuffer.GetOneByte(transactionId_)) {
155         TELEPHONY_LOGE("Decode Transaction Id error.");
156         return false;
157     }
158     pushType_ = 0;
159     if (!decodeBuffer.GetOneByte(pushType_)) {
160         TELEPHONY_LOGE("Decode PushType Error.");
161         return false;
162     }
163     /** 8.2.4 Push and Confirmed Push Facilities **/
164     if (pushType_ != PDU_TYPE_PUSH && pushType_ != PDU_TYPE_CONFIRMED_PUSH) {
165         TELEPHONY_LOGE("unSupported this pushType:%{public}d", pushType_);
166         return false;
167     }
168     return true;
169 }
170 
171 /**
172  * @brief DeocdeCheckIsBlock
173  * Check Block From Address From Contact BataBase
174  * @param pdus [in]
175  * @param len [in]
176  * @return true
177  * @return false
178  */
DeocdeCheckIsBlock(std::string & hexData)179 bool SmsWapPushHandler::DeocdeCheckIsBlock(std::string &hexData)
180 {
181     const uint8_t mmsNotificationInd = 130;
182 
183     std::string pdustr = StringUtils::HexToString(hexData);
184     uint32_t pduLen = pdustr.length();
185 
186     std::unique_ptr<char[]> pdus = std::make_unique<char[]>(pduLen);
187     if (pdus == nullptr || pduLen == 0) {
188         TELEPHONY_LOGE("pdu buffer data param error");
189         return false;
190     }
191     if (memcpy_s(pdus.get(), pduLen, pdustr.data(), pduLen) != EOK) {
192         TELEPHONY_LOGE("Memcpy_s DeocdeCheckIsBlock Error.");
193         return false;
194     }
195 
196     MmsMsg mmsMsg;
197     bool result = mmsMsg.DecodeMsg(std::move(pdus), pduLen);
198     if (result && (mmsMsg.GetMmsMessageType() == mmsNotificationInd)) {
199         mmsMsg.DumpMms();
200         MmsAddress fromAddress = mmsMsg.GetMmsFrom();
201         auto helper = DelayedSingleton<SmsPersistHelper>::GetInstance();
202         if (helper == nullptr) {
203             TELEPHONY_LOGE("SmsPersist Helper nullptr error");
204             return false;
205         }
206         std::string address = fromAddress.GetAddressString();
207         std::size_t pos = address.find('/');
208         if (pos == 0) {
209             TELEPHONY_LOGE("pos invalid.");
210             return false;
211         } else if (pos == std::string::npos) {
212             return helper->QueryBlockPhoneNumber(address);
213         } else {
214             return helper->QueryBlockPhoneNumber(address.substr(0, pos));
215         }
216     }
217     TELEPHONY_LOGI("wap push is not blocked.");
218     return false;
219 }
220 
221 /**
222  * @brief DecodeXwapApplication
223  * WAP-251-PushMessage-20010322-a    5.2.1 5.2.2. WAP Headers
224  * @param decodeBuffer [in]
225  * @param headersLen [in]
226  * @return true
227  * @return false
228  */
DecodeXWapApplication(SmsWapPushBuffer & decodeBuffer,uint32_t headersLen)229 bool SmsWapPushHandler::DecodeXWapApplication(SmsWapPushBuffer &decodeBuffer, uint32_t headersLen)
230 {
231     std::unique_ptr<char[]> tempHeadersBuffer = nullptr;
232     tempHeadersBuffer = decodeBuffer.ReadDataBuffer(headersLen);
233     if (headersLen > 0 && tempHeadersBuffer != nullptr) {
234         SmsWapPushBuffer tempXWapDataBuffer;
235         if (!tempXWapDataBuffer.WriteDataBuffer(std::move(tempHeadersBuffer), headersLen)) {
236             TELEPHONY_LOGE("Wap push WriteDataBuffer fail.");
237             return false;
238         }
239         decodeBuffer.IncreasePointer(headersLen);
240         return DecodeXWapApplicationField(tempXWapDataBuffer, strAppId_);
241     }
242     return false;
243 }
244 
245 /**
246  * @brief DecodeXWapApplicationField
247  * WAP-251-PushMessage-20010322-a    5.2.1 5.2.2. WAP Headers
248  * @param decodeBuffer [in]
249  * @param strWapAppId [out]
250  * @return true
251  * @return false
252  */
DecodeXWapApplicationField(SmsWapPushBuffer & decodeBuffer,std::string & strWapAppId)253 bool SmsWapPushHandler::DecodeXWapApplicationField(SmsWapPushBuffer &decodeBuffer, std::string &strWapAppId)
254 {
255     while (decodeBuffer.GetCurPosition() < decodeBuffer.GetSize()) {
256         uint64_t fieldValue = 0;
257         if (!decodeBuffer.DecodeInteger(fieldValue)) {
258             TELEPHONY_LOGE("Wap push DecodeInteger fail.");
259             return false;
260         }
261         if (fieldValue == PARAMETER_X_WAP_APPLICATION_ID) {
262             return DecodeXWapApplicationValue(decodeBuffer, strWapAppId);
263         } else {
264             DecodeXWapAbandonHeaderValue(decodeBuffer);
265         }
266     }
267     return false;
268 }
269 
270 /*
271  * wap-230-wsp-20010705-a
272  * 8.4.2.54 X-Wap-Application-Id field
273  * The following rule is used to encode the X-Wap-Application-Id field.
274  * Application-id-value = Uri-value | App-assigned-code
275  * App-assigned-code = Integer-value
276  */
DecodeXWapApplicationValue(SmsWapPushBuffer & decodeBuffer,std::string & strWapAppId)277 bool SmsWapPushHandler::DecodeXWapApplicationValue(SmsWapPushBuffer &decodeBuffer, std::string &strWapAppId)
278 {
279     uint64_t appIdValue = 0;
280     if (decodeBuffer.DecodeInteger(appIdValue)) {
281         return true;
282     }
283     uint32_t len = 0;
284     if (!decodeBuffer.DecodeText(strWapAppId, len)) {
285         TELEPHONY_LOGE("Wap push DecodeText fail.");
286         return false;
287     }
288     return true;
289 }
290 
291 /*
292  * wap-230-wsp-20010705-a
293  * 8.4.1.2 Field values, We abancon beyond that X-Wap-Application-Id
294  * Value Interpretation of First Octet
295  * 0 - 30 This octet is followed by the indicated number (0 –30) of data octets
296  * 31 This octet is followed by a uintvar, which indicates the number of data octets after it
297  * 32 - 127 The value is a text string, terminated by a zero octet (NUL character)
298  * 128 - 255 It is an encoded 7-bit value; this header has no more data
299  */
DecodeXWapAbandonHeaderValue(SmsWapPushBuffer & decodeBuffer)300 bool SmsWapPushHandler::DecodeXWapAbandonHeaderValue(SmsWapPushBuffer &decodeBuffer)
301 {
302     const uint8_t wapShortLengthMax = 30;
303     const uint8_t wapLengthQuote = 31;
304     const uint8_t textLengthMax = 127;
305 
306     uint8_t oneByte = 0;
307     if (!decodeBuffer.GetOneByte(oneByte)) {
308         TELEPHONY_LOGE("Wap push GetOneByte fail.");
309         return false;
310     }
311 
312     if (oneByte <= wapShortLengthMax) {
313         if (!decodeBuffer.IncreasePointer(oneByte)) {
314             TELEPHONY_LOGE("Wap push IncreasePointer fail.");
315             return false;
316         }
317     } else if (oneByte == wapLengthQuote) {
318         uint32_t length = 0;
319         uint32_t count = 0;
320         if (!decodeBuffer.DecodeUintvar(length, count)) {
321             TELEPHONY_LOGE("Wap push DecodeUintvar fail.");
322             return false;
323         }
324         if (!decodeBuffer.IncreasePointer(length)) {
325             TELEPHONY_LOGE("Wap push IncreasePointer fail.");
326             return false;
327         }
328     } else if (oneByte <= textLengthMax) {
329         std::string strTemp = "";
330         uint32_t length = 0;
331         if (!decodeBuffer.DecodeText(strTemp, length)) {
332             TELEPHONY_LOGE("Wap push DecodeText fail.");
333             return false;
334         }
335     }
336     return true;
337 }
338 
SendWapPushMessageBroadcast(std::shared_ptr<SmsReceiveIndexer> indexer)339 bool SmsWapPushHandler::SendWapPushMessageBroadcast(std::shared_ptr<SmsReceiveIndexer> indexer)
340 {
341     if (indexer == nullptr) {
342         TELEPHONY_LOGE("indexer is nullptr");
343         return false;
344     }
345     TELEPHONY_LOGI("wap push broadcast slotId:%{public}d", slotId_);
346     EventFwk::Want want;
347     want.SetAction(EventFwk::CommonEventSupport::COMMON_EVENT_SMS_WAPPUSH_RECEIVE_COMPLETED);
348     want.SetParam("slotId", static_cast<int>(slotId_));
349     want.SetParam("pushType", static_cast<int>(pushType_));
350     want.SetParam("applicationId", strAppId_);
351     want.SetParam("transactionId", static_cast<int>(transactionId_));
352     want.SetParam("contentType", contentType_.GetContentType());
353     want.SetParam("headerData", hexHeaderData_);
354     want.SetParam("rawData", hexWbXmlData_);
355     want.SetParam(SmsBroadcastSubscriberReceiver::SMS_BROADCAST_DATABASE_ID_KEY, indexer->GetDataBaseId());
356     want.SetParam(SmsBroadcastSubscriberReceiver::SMS_BROADCAST_MSG_REF_ID_KEY, indexer->GetMsgRefId());
357     want.SetParam(SmsBroadcastSubscriberReceiver::SMS_BROADCAST_ADDRESS_KEY, indexer->GetOriginatingAddress());
358 
359     EventFwk::CommonEventData data;
360     data.SetWant(want);
361     data.SetData("Sms WapPush Message");
362     data.SetCode(0);
363     EventFwk::CommonEventPublishInfo publishInfo;
364     publishInfo.SetOrdered(true);
365     std::vector<std::string> wappushPermissions;
366     wappushPermissions.emplace_back(Permission::RECEIVE_MMS);
367     publishInfo.SetSubscriberPermissions(wappushPermissions);
368 
369     bool publishResult = EventFwk::CommonEventManager::PublishCommonEvent(data, publishInfo, g_receiver);
370     HiSysEventWapPushResult(publishResult);
371     return true;
372 }
373 
HiSysEventWapPushResult(bool publishResult)374 void SmsWapPushHandler::HiSysEventWapPushResult(bool publishResult)
375 {
376     if (!publishResult) {
377         TELEPHONY_LOGE("SendBroadcast PublishBroadcastEvent result fail");
378         SmsHiSysEvent::WriteSmsReceiveFaultEvent(slotId_, SmsMmsMessageType::WAP_PUSH,
379             SmsMmsErrorCode::SMS_ERROR_PUBLISH_COMMON_EVENT_FAIL, "publish wpa push broadcast event fail");
380     }
381     DelayedSingleton<SmsHiSysEvent>::GetInstance()->SetWapPushBroadcastStartTime();
382 }
383 } // namespace Telephony
384 } // namespace OHOS
385