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