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