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