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