Fixed the build error using gcc 13
[platform/core/messaging/msg-service.git] / externals / MsgSpamFilter.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15 */
16
17 #include "MsgDebug.h"
18 #include "MsgUtilFile.h"
19 #include "MsgUtilFunction.h"
20 #include "MsgCppTypes.h"
21 #include "MsgGconfWrapper.h"
22 #include "MsgSpamFilter.h"
23
24 #include <phone_number.h>
25
26 /*==================================================================================================
27                                      FUNCTION IMPLEMENTATION
28 ==================================================================================================*/
29 msg_error_t MsgSetFilterOperation(bool bSetFlag)
30 {
31         MSG_BEGIN();
32
33         if (MsgSettingSetBool(MSG_BLOCK_MESSAGE, bSetFlag) != MSG_SUCCESS) {
34                 MSG_DEBUG("Error to set config data [%s]", MSG_BLOCK_MESSAGE);
35                 return MSG_ERR_SET_SETTING;
36         }
37
38         MSG_END();
39
40         return MSG_SUCCESS;
41 }
42
43
44 msg_error_t MsgGetFilterOperation(bool *pSetFlag)
45 {
46         MSG_BEGIN();
47
48         if (MsgSettingGetBool(MSG_BLOCK_MESSAGE, pSetFlag) != MSG_SUCCESS)
49                 MSG_INFO("MsgSettingGetBool() is failed");
50
51         MSG_END();
52
53         return MSG_SUCCESS;
54 }
55
56
57 bool MsgCheckFilter(MsgDbHandler *pDbHandle, MSG_MESSAGE_INFO_S *pMsgInfo)
58 {
59         MSG_BEGIN();
60
61         msg_error_t err = MSG_SUCCESS;
62
63         /*========================================================================
64            Check Unknown Sender
65         ========================================================================*/
66         bool bBlockUnknown = false;
67
68         if (MsgSettingGetBool(MSG_BLOCK_UNKNOWN_MSG, &bBlockUnknown) == MSG_SUCCESS) {
69                 if (bBlockUnknown == true && pMsgInfo->addressList[0].addressVal[0] == '\0') {
70                         MSG_DEBUG("Unknown sender message!!");
71                         return true;
72                 }
73         }
74
75         /*========================================================================
76            Check Filter Operation
77         ========================================================================*/
78         bool filterFlag = false;
79
80         MsgGetFilterOperation(&filterFlag);
81
82         if (filterFlag == false) {
83                 MSG_DEBUG("filter operation is not working");
84                 return false;
85         }
86
87         /*========================================================================
88            Check Filter by Address
89         ========================================================================*/
90         int rowCnt = 0;
91         char sqlQuery[MAX_QUERY_LEN+1];
92
93         MSG_SEC_DEBUG("pMsg->addressList[0].addressVal [%s]", pMsgInfo->addressList[0].addressVal);
94 #if 1 /* use phonenumber-utils API */
95         bool is_blocking = false;
96         int ret = PHONE_NUMBER_ERROR_NONE;
97
98         ret = phone_number_connect();
99         if (ret != PHONE_NUMBER_ERROR_NONE)
100                 MSG_WARN("phone_number_connect failed! [%d]", ret);
101
102         ret = phone_number_check_blocking(pMsgInfo->addressList[0].addressVal, &is_blocking);
103         if (ret != PHONE_NUMBER_ERROR_NONE)
104                 MSG_WARN("phone_number_check_blocking failed! [%d]", ret);
105
106         ret = phone_number_disconnect();
107         if (ret != PHONE_NUMBER_ERROR_NONE)
108                 MSG_WARN("phone_number_disconnect failed! [%d]", ret);
109
110
111         if (is_blocking == true) {
112                 MSG_SEC_DEBUG("Msg is Filtered by Address : [%s]", pMsgInfo->addressList[0].addressVal);
113                 pMsgInfo->folderId = MSG_SPAMBOX_ID;
114                 return true;
115         }
116 #else
117         memset(sqlQuery, 0x00, sizeof(sqlQuery));
118         snprintf(sqlQuery, sizeof(sqlQuery), "SELECT FILTER_ID FROM %s WHERE FILTER_TYPE = %d AND '%s' LIKE (CASE WHEN LENGTH(FILTER_VALUE) > %d-1 THEN '%%' || SUBSTR(FILTER_VALUE, LENGTH(FILTER_VALUE)-%d+1) ELSE FILTER_VALUE END) AND FILTER_ACTIVE = 1 \
119                         UNION SELECT FILTER_ID FROM %s WHERE FILTER_TYPE = %d AND '%s' LIKE SUBSTR(FILTER_VALUE, 1) || '%%' AND FILTER_ACTIVE = 1 \
120                         UNION SELECT FILTER_ID FROM %s WHERE FILTER_TYPE = %d AND '%s' LIKE '%%' || SUBSTR(FILTER_VALUE, 1) || '%%' AND FILTER_ACTIVE = 1 \
121                         UNION SELECT FILTER_ID FROM %s WHERE FILTER_TYPE = %d AND '%s' LIKE '%%' || SUBSTR(FILTER_VALUE, 1) AND FILTER_ACTIVE = 1;",
122                         MSGFW_FILTER_TABLE_NAME, MSG_FILTER_BY_ADDRESS_SAME, pMsgInfo->addressList[0].addressVal, MsgContactGetMinMatchDigit(), MsgContactGetMinMatchDigit(),
123                         MSGFW_FILTER_TABLE_NAME, MSG_FILTER_BY_ADDRESS_START, pMsgInfo->addressList[0].addressVal,
124                         MSGFW_FILTER_TABLE_NAME, MSG_FILTER_BY_ADDRESS_INCLUDE, pMsgInfo->addressList[0].addressVal,
125                         MSGFW_FILTER_TABLE_NAME, MSG_FILTER_BY_ADDRESS_END, pMsgInfo->addressList[0].addressVal);
126
127         err = pDbHandle->getTable(sqlQuery, &rowCnt, NULL);
128
129         if (rowCnt > 0) {
130                 MSG_SEC_DEBUG("Msg is Filtered by Address : [%s]", pMsgInfo->addressList[0].addressVal);
131                 pDbHandle->freeTable();
132                 pMsgInfo->folderId = MSG_SPAMBOX_ID;
133                 return true;
134         } else {
135                 MSG_SEC_DEBUG("Msg is NOT Filtered by Address : [%s]", pMsgInfo->addressList[0].addressVal);
136                 pDbHandle->freeTable();
137         }
138 #endif
139         /*========================================================================
140            Check Filter by Subject
141         ========================================================================*/
142         /* Get Filter List */
143         memset(sqlQuery, 0x00, sizeof(sqlQuery));
144
145         snprintf(sqlQuery, sizeof(sqlQuery), "SELECT FILTER_VALUE FROM %s WHERE FILTER_TYPE = %d;",
146                         MSGFW_FILTER_TABLE_NAME, MSG_FILTER_BY_WORD);
147
148         rowCnt = 0;
149
150         err = pDbHandle->getTable(sqlQuery, &rowCnt, NULL);
151
152         if (err != MSG_SUCCESS) {
153                 MSG_DEBUG("Fail to getTable().");
154                 pDbHandle->freeTable();
155                 return false;
156         }
157
158         char filterValue[MAX_FILTER_VALUE_LEN+1];
159
160         char* pData = NULL;
161         unique_ptr<char*, void(*)(char**)> buf(&pData, unique_ptr_deleter);
162
163         int fileSize = 0;
164         bool bFiltered = false;
165         unsigned int tmpLen = 0;
166         for (int i = 1; i <= rowCnt; i++) {
167                 memset(filterValue, 0x00, sizeof(filterValue));
168
169                 pDbHandle->getColumnToString(i, MAX_FILTER_VALUE_LEN, filterValue);
170
171                 MSG_DEBUG("filterValue [%s]", filterValue);
172
173                 if (strlen(filterValue) <= 0)
174                         continue;
175
176                 if (pMsgInfo->msgType.mainType == MSG_SMS_TYPE && pMsgInfo->msgType.subType == MSG_NORMAL_SMS) {
177                         if (pMsgInfo->bTextSms == false) {
178                                 if (pData) {
179                                         delete[] pData;
180                                         pData = NULL;
181                                 }
182
183                                 if (MsgOpenAndReadFile(pMsgInfo->msgData, &pData, &fileSize) == false) {
184                                         pDbHandle->freeTable();
185                                         return false;
186                                 }
187                                 MSG_DEBUG("file data [%s]", pData);
188                         } else {
189                                 if (pMsgInfo->dataSize > 0) {
190                                         if (pData) {
191                                                 delete[] pData;
192                                                 pData = NULL;
193                                         }
194
195                                         pData = new char[pMsgInfo->dataSize+1];
196
197                                         strncpy(pData, pMsgInfo->msgText, pMsgInfo->dataSize);
198                                         tmpLen = strlen(pMsgInfo->msgText);
199                                         if ( tmpLen < pMsgInfo->dataSize)
200                                                 pData[tmpLen] = '\0';
201                                         else
202                                                 pData[pMsgInfo->dataSize] = '\0';
203                                 }
204                         }
205                 } else if (pMsgInfo->msgType.mainType == MSG_MMS_TYPE) {
206                         tmpLen = strlen(pMsgInfo->subject);
207                         if (tmpLen > 0) {
208                                 if (pData) {
209                                         delete[] pData;
210                                         pData = NULL;
211                                 }
212
213                                 pData = new char[tmpLen+1];
214
215                                 strncpy(pData, pMsgInfo->subject, tmpLen);
216                                 pData[tmpLen] = '\0';
217                         }
218                 }
219
220                 /* NULL value check */
221                 if (pData == NULL) {
222                         MSG_DEBUG("pData is NULL");
223
224                         bFiltered = false;
225                         break;
226                 }
227
228                 MSG_DEBUG("pData [%s]", pData);
229
230                 if (strcasestr(pData, filterValue) != NULL) {
231 #if 0
232                         MSG_CONTACT_INFO_S contactInfo;
233                         memset(&contactInfo, 0x00, sizeof(MSG_CONTACT_INFO_S));
234
235                         /* Get Contact Info */
236                         if (MsgGetContactInfo(&(pMsgInfo->addressList[0]), &contactInfo) == MSG_SUCCESS) {
237                                 if (contactInfo.contactId > 0) {
238                                         MSG_SEC_DEBUG("Msg is Filtered by Subject [%s] Data [%s], but address is in contact. Skip.", filterValue, pData);
239                                 } else {
240                                         MSG_DEBUG("Msg is Filtered by Subject [%s] Data [%s]", filterValue, pData);
241                                         bFiltered = true;
242                                         break;
243                                 }
244                         } else {
245                                 MSG_DEBUG("MsgGetContactInfo() fail.");
246                         }
247 #else
248                         MSG_DEBUG("Msg is Filtered by Subject [%s] Data [%s]", filterValue, pData);
249                         bFiltered = true;
250                         break;
251 #endif
252                 }
253         }
254
255         pDbHandle->freeTable();
256
257         if (bFiltered == true) {
258                 MSG_DEBUG("Msg is Filtered by Subject");
259
260                 pMsgInfo->folderId = MSG_SPAMBOX_ID;
261
262                 return true;
263         } else {
264                 MSG_DEBUG("Msg is NOT Filtered by Subject");
265         }
266
267         MSG_END();
268
269         return false;
270 }
271
272
273 bool MsgCheckFilterByWord(MsgDbHandler *pDbHandle, const char *pMsgText)
274 {
275         MSG_BEGIN();
276
277         if (!pMsgText) {
278                 MSG_DEBUG("pMsgText is NULL");
279                 return false;
280         }
281
282         msg_error_t err = MSG_SUCCESS;
283
284         /*========================================================================
285            Check Filter Operation
286         ========================================================================*/
287         bool filterFlag = false;
288
289         MsgGetFilterOperation(&filterFlag);
290
291         if (filterFlag == false) {
292                 MSG_DEBUG("filter operation is not working");
293                 return false;
294         }
295
296         int rowCnt = 0;
297         char sqlQuery[MAX_QUERY_LEN+1];
298
299         memset(sqlQuery, 0x00, sizeof(sqlQuery));
300
301
302         /*========================================================================
303            Check Filter by Word
304         ========================================================================*/
305         /* Get Filter List */
306         memset(sqlQuery, 0x00, sizeof(sqlQuery));
307
308         snprintf(sqlQuery, sizeof(sqlQuery), "SELECT FILTER_VALUE FROM %s WHERE FILTER_TYPE = %d;",
309                         MSGFW_FILTER_TABLE_NAME, MSG_FILTER_BY_WORD);
310
311         err = pDbHandle->getTable(sqlQuery, &rowCnt, NULL);
312
313         if (err != MSG_SUCCESS) {
314                 MSG_DEBUG("Fail to getTable().");
315                 pDbHandle->freeTable();
316                 return false;
317         }
318
319         char filterValue[MAX_FILTER_VALUE_LEN+1];
320         bool bFiltered = false;
321
322         for (int i = 1; i <= rowCnt; i++) {
323                 memset(filterValue, 0x00, sizeof(filterValue));
324
325                 pDbHandle->getColumnToString(i, MAX_FILTER_VALUE_LEN, filterValue);
326
327                 MSG_DEBUG("filterValue [%s]", filterValue);
328
329                 if (strlen(filterValue) <= 0)
330                         continue;
331
332                 if (strcasestr(pMsgText, filterValue) != NULL) {
333                         MSG_DEBUG("Msg is Filtered by Word [%s] ", filterValue);
334                         bFiltered = true;
335                         break;
336                 }
337         }
338
339         pDbHandle->freeTable();
340
341         MSG_END();
342
343         return bFiltered;
344 }
345
346