• 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 "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