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 }
209 TELEPHONY_LOGI("wap push is not blocked.");
210 return false;
211 }
212
213 /**
214 * @brief DecodeXwapApplication
215 * WAP-251-PushMessage-20010322-a 5.2.1 5.2.2. WAP Headers
216 * @param decodeBuffer [in]
217 * @param headersLen [in]
218 * @return true
219 * @return false
220 */
DecodeXWapApplication(SmsWapPushBuffer & decodeBuffer,uint32_t headersLen)221 bool SmsWapPushHandler::DecodeXWapApplication(SmsWapPushBuffer &decodeBuffer, uint32_t headersLen)
222 {
223 std::unique_ptr<char[]> tempHeadersBuffer = nullptr;
224 tempHeadersBuffer = decodeBuffer.ReadDataBuffer(headersLen);
225 if (headersLen > 0 && tempHeadersBuffer != nullptr) {
226 SmsWapPushBuffer tempXWapDataBuffer;
227 if (!tempXWapDataBuffer.WriteDataBuffer(std::move(tempHeadersBuffer), headersLen)) {
228 TELEPHONY_LOGE("Wap push WriteDataBuffer fail.");
229 return false;
230 }
231 decodeBuffer.IncreasePointer(headersLen);
232 return DecodeXWapApplicationField(tempXWapDataBuffer, strAppId_);
233 }
234 return false;
235 }
236
237 /**
238 * @brief DecodeXWapApplicationField
239 * WAP-251-PushMessage-20010322-a 5.2.1 5.2.2. WAP Headers
240 * @param decodeBuffer [in]
241 * @param strWapAppId [out]
242 * @return true
243 * @return false
244 */
DecodeXWapApplicationField(SmsWapPushBuffer & decodeBuffer,std::string & strWapAppId)245 bool SmsWapPushHandler::DecodeXWapApplicationField(SmsWapPushBuffer &decodeBuffer, std::string &strWapAppId)
246 {
247 while (decodeBuffer.GetCurPosition() < decodeBuffer.GetSize()) {
248 uint64_t fieldValue = 0;
249 if (!decodeBuffer.DecodeInteger(fieldValue)) {
250 TELEPHONY_LOGE("Wap push DecodeInteger fail.");
251 return false;
252 }
253 if (fieldValue == PARAMETER_X_WAP_APPLICATION_ID) {
254 return DecodeXWapApplicationValue(decodeBuffer, strWapAppId);
255 } else {
256 DecodeXWapAbandonHeaderValue(decodeBuffer);
257 }
258 }
259 return false;
260 }
261
262 /*
263 * wap-230-wsp-20010705-a
264 * 8.4.2.54 X-Wap-Application-Id field
265 * The following rule is used to encode the X-Wap-Application-Id field.
266 * Application-id-value = Uri-value | App-assigned-code
267 * App-assigned-code = Integer-value
268 */
DecodeXWapApplicationValue(SmsWapPushBuffer & decodeBuffer,std::string & strWapAppId)269 bool SmsWapPushHandler::DecodeXWapApplicationValue(SmsWapPushBuffer &decodeBuffer, std::string &strWapAppId)
270 {
271 uint64_t appIdValue = 0;
272 if (decodeBuffer.DecodeInteger(appIdValue)) {
273 return true;
274 }
275 uint32_t len = 0;
276 if (!decodeBuffer.DecodeText(strWapAppId, len)) {
277 TELEPHONY_LOGE("Wap push DecodeText fail.");
278 return false;
279 }
280 return true;
281 }
282
283 /*
284 * wap-230-wsp-20010705-a
285 * 8.4.1.2 Field values, We abancon beyond that X-Wap-Application-Id
286 * Value Interpretation of First Octet
287 * 0 - 30 This octet is followed by the indicated number (0 –30) of data octets
288 * 31 This octet is followed by a uintvar, which indicates the number of data octets after it
289 * 32 - 127 The value is a text string, terminated by a zero octet (NUL character)
290 * 128 - 255 It is an encoded 7-bit value; this header has no more data
291 */
DecodeXWapAbandonHeaderValue(SmsWapPushBuffer & decodeBuffer)292 bool SmsWapPushHandler::DecodeXWapAbandonHeaderValue(SmsWapPushBuffer &decodeBuffer)
293 {
294 const uint8_t wapShortLengthMax = 30;
295 const uint8_t wapLengthQuote = 31;
296 const uint8_t textLengthMax = 127;
297
298 uint8_t oneByte = 0;
299 if (!decodeBuffer.GetOneByte(oneByte)) {
300 TELEPHONY_LOGE("Wap push GetOneByte fail.");
301 return false;
302 }
303
304 if (oneByte <= wapShortLengthMax) {
305 if (!decodeBuffer.IncreasePointer(oneByte)) {
306 TELEPHONY_LOGE("Wap push IncreasePointer fail.");
307 return false;
308 }
309 } else if (oneByte == wapLengthQuote) {
310 uint32_t length = 0;
311 uint32_t count = 0;
312 if (!decodeBuffer.DecodeUintvar(length, count)) {
313 TELEPHONY_LOGE("Wap push DecodeUintvar fail.");
314 return false;
315 }
316 if (!decodeBuffer.IncreasePointer(length)) {
317 TELEPHONY_LOGE("Wap push IncreasePointer fail.");
318 return false;
319 }
320 } else if (oneByte <= textLengthMax) {
321 std::string strTemp = "";
322 uint32_t length = 0;
323 if (!decodeBuffer.DecodeText(strTemp, length)) {
324 TELEPHONY_LOGE("Wap push DecodeText fail.");
325 return false;
326 }
327 }
328 return true;
329 }
330
SendWapPushMessageBroadcast(std::shared_ptr<SmsReceiveIndexer> indexer)331 bool SmsWapPushHandler::SendWapPushMessageBroadcast(std::shared_ptr<SmsReceiveIndexer> indexer)
332 {
333 if (indexer == nullptr) {
334 TELEPHONY_LOGE("indexer is nullptr");
335 return false;
336 }
337 TELEPHONY_LOGI("wap push broadcast slotId:%{public}d", slotId_);
338 EventFwk::Want want;
339 want.SetAction(EventFwk::CommonEventSupport::COMMON_EVENT_SMS_WAPPUSH_RECEIVE_COMPLETED);
340 want.SetParam("slotId", static_cast<int>(slotId_));
341 want.SetParam("pushType", static_cast<int>(pushType_));
342 want.SetParam("applicationId", strAppId_);
343 want.SetParam("transactionId", static_cast<int>(transactionId_));
344 want.SetParam("contentType", contentType_.GetContentType());
345 want.SetParam("headerData", hexHeaderData_);
346 want.SetParam("rawData", hexWbXmlData_);
347
348 EventFwk::CommonEventData data;
349 data.SetWant(want);
350 data.SetData("Sms WapPush Message");
351 data.SetCode(0);
352 EventFwk::CommonEventPublishInfo publishInfo;
353 publishInfo.SetOrdered(true);
354 std::vector<std::string> wappushPermissions;
355 wappushPermissions.emplace_back(Permission::RECEIVE_MMS);
356 publishInfo.SetSubscriberPermissions(wappushPermissions);
357
358 MatchingSkills smsSkills;
359 smsSkills.AddEvent(CommonEventSupport::COMMON_EVENT_SMS_WAPPUSH_RECEIVE_COMPLETED);
360 CommonEventSubscribeInfo smsSubscriberInfo(smsSkills);
361 smsSubscriberInfo.SetThreadMode(EventFwk::CommonEventSubscribeInfo::COMMON);
362 auto handler = std::make_shared<SmsReceiveReliabilityHandler>(slotId_);
363 auto wapPushReceiver = std::make_shared<SmsBroadcastSubscriberReceiver>(
364 smsSubscriberInfo, handler, indexer->GetMsgRefId(), indexer->GetDataBaseId(), indexer->GetOriginatingAddress());
365 bool publishResult = EventFwk::CommonEventManager::PublishCommonEvent(data, publishInfo, wapPushReceiver);
366 sptrQueue.push(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