70 REFERENCES threat_list(threat_type, platform_type, threat_entry_type) |
75 REFERENCES threat_list(threat_type, platform_type, threat_entry_type) |
71 ON DELETE CASCADE |
76 ON DELETE CASCADE |
72 ) |
77 ) |
73 """ |
78 """ |
74 drop_hash_prefix_stmt = """DROP TABLE IF EXISTS hash_prefix""" |
79 drop_hash_prefix_stmt = """DROP TABLE IF EXISTS hash_prefix""" |
75 |
80 |
76 create_full_hash_cue_idx = """ |
81 create_full_hash_cue_idx = """ |
77 CREATE INDEX idx_hash_prefix_cue ON hash_prefix (cue) |
82 CREATE INDEX idx_hash_prefix_cue ON hash_prefix (cue) |
78 """ |
83 """ |
79 drop_full_hash_cue_idx = """DROP INDEX IF EXISTS idx_hash_prefix_cue""" |
84 drop_full_hash_cue_idx = """DROP INDEX IF EXISTS idx_hash_prefix_cue""" |
80 |
85 |
81 create_full_hash_expires_idx = """ |
86 create_full_hash_expires_idx = """ |
82 CREATE INDEX idx_full_hash_expires_at ON full_hash (expires_at) |
87 CREATE INDEX idx_full_hash_expires_at ON full_hash (expires_at) |
83 """ |
88 """ |
84 drop_full_hash_expires_idx = """ |
89 drop_full_hash_expires_idx = """ |
85 DROP INDEX IF EXISTS idx_full_hash_expires_at |
90 DROP INDEX IF EXISTS idx_full_hash_expires_at |
86 """ |
91 """ |
87 |
92 |
88 create_full_hash_value_idx = """ |
93 create_full_hash_value_idx = """ |
89 CREATE INDEX idx_full_hash_value ON full_hash (value) |
94 CREATE INDEX idx_full_hash_value ON full_hash (value) |
90 """ |
95 """ |
91 drop_full_hash_value_idx = """DROP INDEX IF EXISTS idx_full_hash_value""" |
96 drop_full_hash_value_idx = """DROP INDEX IF EXISTS idx_full_hash_value""" |
92 |
97 |
93 maxProcessEventsTime = 500 |
98 maxProcessEventsTime = 500 |
94 |
99 |
95 def __init__(self, dbPath, parent=None): |
100 def __init__(self, dbPath, parent=None): |
96 """ |
101 """ |
97 Constructor |
102 Constructor |
98 |
103 |
99 @param dbPath path to store the cache DB into |
104 @param dbPath path to store the cache DB into |
100 @type str |
105 @type str |
101 @param parent reference to the parent object |
106 @param parent reference to the parent object |
102 @type QObject |
107 @type QObject |
103 """ |
108 """ |
104 super().__init__(parent) |
109 super().__init__(parent) |
105 |
110 |
106 self.__connectionName = "SafeBrowsingCache" |
111 self.__connectionName = "SafeBrowsingCache" |
107 |
112 |
108 if not os.path.exists(dbPath): |
113 if not os.path.exists(dbPath): |
109 os.makedirs(dbPath) |
114 os.makedirs(dbPath) |
110 |
115 |
111 self.__dbFileName = os.path.join(dbPath, "SafeBrowsingCache.db") |
116 self.__dbFileName = os.path.join(dbPath, "SafeBrowsingCache.db") |
112 preparationNeeded = not os.path.exists(self.__dbFileName) |
117 preparationNeeded = not os.path.exists(self.__dbFileName) |
113 |
118 |
114 self.__openCacheDb() |
119 self.__openCacheDb() |
115 if preparationNeeded: |
120 if preparationNeeded: |
116 self.prepareCacheDb() |
121 self.prepareCacheDb() |
117 |
122 |
118 def close(self): |
123 def close(self): |
119 """ |
124 """ |
120 Public method to close the database. |
125 Public method to close the database. |
121 """ |
126 """ |
122 if QSqlDatabase.database(self.__connectionName).isOpen(): |
127 if QSqlDatabase.database(self.__connectionName).isOpen(): |
123 QSqlDatabase.database(self.__connectionName).close() |
128 QSqlDatabase.database(self.__connectionName).close() |
124 QSqlDatabase.removeDatabase(self.__connectionName) |
129 QSqlDatabase.removeDatabase(self.__connectionName) |
125 |
130 |
126 def __openCacheDb(self): |
131 def __openCacheDb(self): |
127 """ |
132 """ |
128 Private method to open the cache database. |
133 Private method to open the cache database. |
129 |
134 |
130 @return flag indicating the open state |
135 @return flag indicating the open state |
131 @rtype bool |
136 @rtype bool |
132 """ |
137 """ |
133 db = QSqlDatabase.database(self.__connectionName, False) |
138 db = QSqlDatabase.database(self.__connectionName, False) |
134 if not db.isValid(): |
139 if not db.isValid(): |
185 SELECT threat_type, platform_type, threat_entry_type, |
190 SELECT threat_type, platform_type, threat_entry_type, |
186 expires_at < current_timestamp AS has_expired |
191 expires_at < current_timestamp AS has_expired |
187 FROM full_hash WHERE value IN ({0}) |
192 FROM full_hash WHERE value IN ({0}) |
188 """ |
193 """ |
189 output = [] |
194 output = [] |
190 |
195 |
191 db = QSqlDatabase.database(self.__connectionName) |
196 db = QSqlDatabase.database(self.__connectionName) |
192 if db.isOpen(): |
197 if db.isOpen(): |
193 db.transaction() |
198 db.transaction() |
194 try: |
199 try: |
195 query = QSqlQuery(db) |
200 query = QSqlQuery(db) |
196 query.prepare( |
201 query.prepare(queryStr.format(",".join(["?"] * len(hashValues)))) |
197 queryStr.format(",".join(["?"] * len(hashValues)))) |
|
198 for hashValue in hashValues: |
202 for hashValue in hashValues: |
199 query.addBindValue( |
203 query.addBindValue( |
200 QByteArray(hashValue), |
204 QByteArray(hashValue), |
201 QSql.ParamTypeFlag.In | QSql.ParamTypeFlag.Binary) |
205 QSql.ParamTypeFlag.In | QSql.ParamTypeFlag.Binary, |
202 |
206 ) |
203 query.exec() |
207 |
204 |
208 query.exec() |
205 while query.next(): # __IGNORE_WARNING_M523__ |
209 |
|
210 while query.next(): # __IGNORE_WARNING_M523__ |
206 threatType = query.value(0) |
211 threatType = query.value(0) |
207 platformType = query.value(1) |
212 platformType = query.value(1) |
208 threatEntryType = query.value(2) |
213 threatEntryType = query.value(2) |
209 hasExpired = bool(query.value(3)) |
214 hasExpired = bool(query.value(3)) |
210 threatList = ThreatList(threatType, platformType, |
215 threatList = ThreatList(threatType, platformType, threatEntryType) |
211 threatEntryType) |
|
212 output.append((threatList, hasExpired)) |
216 output.append((threatList, hasExpired)) |
213 QCoreApplication.processEvents( |
217 QCoreApplication.processEvents( |
214 QEventLoop.ProcessEventsFlag.AllEvents, |
218 QEventLoop.ProcessEventsFlag.AllEvents, |
215 self.maxProcessEventsTime) |
219 self.maxProcessEventsTime, |
216 del query |
220 ) |
217 finally: |
221 del query |
218 db.commit() |
222 finally: |
219 |
223 db.commit() |
|
224 |
220 return output |
225 return output |
221 |
226 |
222 def lookupHashPrefix(self, prefixes): |
227 def lookupHashPrefix(self, prefixes): |
223 """ |
228 """ |
224 Public method to look up hash prefixes in the local cache. |
229 Public method to look up hash prefixes in the local cache. |
225 |
230 |
226 @param prefixes list of hash prefixes to look up |
231 @param prefixes list of hash prefixes to look up |
227 @type list of bytes |
232 @type list of bytes |
228 @return list of tuples containing the threat list, full hash and |
233 @return list of tuples containing the threat list, full hash and |
229 negative cache expiration flag |
234 negative cache expiration flag |
230 @rtype list of tuple of (ThreatList, bytes, bool) |
235 @rtype list of tuple of (ThreatList, bytes, bool) |
233 SELECT value,threat_type,platform_type,threat_entry_type, |
238 SELECT value,threat_type,platform_type,threat_entry_type, |
234 negative_expires_at < current_timestamp AS negative_cache_expired |
239 negative_expires_at < current_timestamp AS negative_cache_expired |
235 FROM hash_prefix WHERE cue IN ({0}) |
240 FROM hash_prefix WHERE cue IN ({0}) |
236 """ |
241 """ |
237 output = [] |
242 output = [] |
238 |
243 |
239 db = QSqlDatabase.database(self.__connectionName) |
244 db = QSqlDatabase.database(self.__connectionName) |
240 if db.isOpen(): |
245 if db.isOpen(): |
241 db.transaction() |
246 db.transaction() |
242 try: |
247 try: |
243 query = QSqlQuery(db) |
248 query = QSqlQuery(db) |
244 query.prepare( |
249 query.prepare(queryStr.format(",".join(["?"] * len(prefixes)))) |
245 queryStr.format(",".join(["?"] * len(prefixes)))) |
|
246 for prefix in prefixes: |
250 for prefix in prefixes: |
247 query.addBindValue(prefix) |
251 query.addBindValue(prefix) |
248 |
252 |
249 query.exec() |
253 query.exec() |
250 |
254 |
251 while query.next(): # __IGNORE_WARNING_M523__ |
255 while query.next(): # __IGNORE_WARNING_M523__ |
252 fullHash = bytes(query.value(0)) |
256 fullHash = bytes(query.value(0)) |
253 threatType = query.value(1) |
257 threatType = query.value(1) |
254 platformType = query.value(2) |
258 platformType = query.value(2) |
255 threatEntryType = query.value(3) |
259 threatEntryType = query.value(3) |
256 negativeCacheExpired = bool(query.value(4)) |
260 negativeCacheExpired = bool(query.value(4)) |
257 threatList = ThreatList(threatType, platformType, |
261 threatList = ThreatList(threatType, platformType, threatEntryType) |
258 threatEntryType) |
|
259 output.append((threatList, fullHash, negativeCacheExpired)) |
262 output.append((threatList, fullHash, negativeCacheExpired)) |
260 QCoreApplication.processEvents( |
263 QCoreApplication.processEvents( |
261 QEventLoop.ProcessEventsFlag.AllEvents, |
264 QEventLoop.ProcessEventsFlag.AllEvents, |
262 self.maxProcessEventsTime) |
265 self.maxProcessEventsTime, |
263 del query |
266 ) |
264 finally: |
267 del query |
265 db.commit() |
268 finally: |
266 |
269 db.commit() |
|
270 |
267 return output |
271 return output |
268 |
272 |
269 def storeFullHash(self, threatList, hashValue, cacheDuration, |
273 def storeFullHash(self, threatList, hashValue, cacheDuration, malwareThreatType): |
270 malwareThreatType): |
|
271 """ |
274 """ |
272 Public method to store full hash data in the cache database. |
275 Public method to store full hash data in the cache database. |
273 |
276 |
274 @param threatList threat list info object |
277 @param threatList threat list info object |
275 @type ThreatList |
278 @type ThreatList |
276 @param hashValue hash to be stored |
279 @param hashValue hash to be stored |
277 @type bytes |
280 @type bytes |
278 @param cacheDuration duration the data should remain in the cache |
281 @param cacheDuration duration the data should remain in the cache |
285 (value, threat_type, platform_type, threat_entry_type, |
288 (value, threat_type, platform_type, threat_entry_type, |
286 malware_threat_type, downloaded_at) |
289 malware_threat_type, downloaded_at) |
287 VALUES |
290 VALUES |
288 (?, ?, ?, ?, ?, current_timestamp) |
291 (?, ?, ?, ?, ?, current_timestamp) |
289 """ |
292 """ |
290 updateQueryStr = ( |
293 updateQueryStr = """ |
291 """ |
|
292 UPDATE full_hash SET |
294 UPDATE full_hash SET |
293 expires_at=datetime(current_timestamp, '+{0} SECONDS') |
295 expires_at=datetime(current_timestamp, '+{0} SECONDS') |
294 WHERE value=? AND threat_type=? AND platform_type=? AND |
296 WHERE value=? AND threat_type=? AND platform_type=? AND |
295 threat_entry_type=? |
297 threat_entry_type=? |
296 """.format(int(cacheDuration)) |
298 """.format( |
|
299 int(cacheDuration) |
297 ) |
300 ) |
298 |
301 |
299 db = QSqlDatabase.database(self.__connectionName) |
302 db = QSqlDatabase.database(self.__connectionName) |
300 if db.isOpen(): |
303 if db.isOpen(): |
301 db.transaction() |
304 db.transaction() |
302 try: |
305 try: |
303 query = QSqlQuery(db) |
306 query = QSqlQuery(db) |
304 query.prepare(insertQueryStr) |
307 query.prepare(insertQueryStr) |
305 query.addBindValue( |
308 query.addBindValue( |
306 QByteArray(hashValue), |
309 QByteArray(hashValue), |
307 QSql.ParamTypeFlag.In | QSql.ParamTypeFlag.Binary) |
310 QSql.ParamTypeFlag.In | QSql.ParamTypeFlag.Binary, |
|
311 ) |
308 query.addBindValue(threatList.threatType) |
312 query.addBindValue(threatList.threatType) |
309 query.addBindValue(threatList.platformType) |
313 query.addBindValue(threatList.platformType) |
310 query.addBindValue(threatList.threatEntryType) |
314 query.addBindValue(threatList.threatEntryType) |
311 query.addBindValue(malwareThreatType) |
315 query.addBindValue(malwareThreatType) |
312 query.exec() |
316 query.exec() |
313 del query |
317 del query |
314 |
318 |
315 query = QSqlQuery(db) |
319 query = QSqlQuery(db) |
316 query.prepare(updateQueryStr) |
320 query.prepare(updateQueryStr) |
317 query.addBindValue( |
321 query.addBindValue( |
318 QByteArray(hashValue), |
322 QByteArray(hashValue), |
319 QSql.ParamTypeFlag.In | QSql.ParamTypeFlag.Binary) |
323 QSql.ParamTypeFlag.In | QSql.ParamTypeFlag.Binary, |
320 query.addBindValue(threatList.threatType) |
324 ) |
321 query.addBindValue(threatList.platformType) |
325 query.addBindValue(threatList.threatType) |
322 query.addBindValue(threatList.threatEntryType) |
326 query.addBindValue(threatList.platformType) |
323 query.exec() |
327 query.addBindValue(threatList.threatEntryType) |
324 del query |
328 query.exec() |
325 finally: |
329 del query |
326 db.commit() |
330 finally: |
327 |
331 db.commit() |
|
332 |
328 def deleteHashPrefixList(self, threatList): |
333 def deleteHashPrefixList(self, threatList): |
329 """ |
334 """ |
330 Public method to delete hash prefixes for a given threat list. |
335 Public method to delete hash prefixes for a given threat list. |
331 |
336 |
332 @param threatList threat list info object |
337 @param threatList threat list info object |
333 @type ThreatList |
338 @type ThreatList |
334 """ |
339 """ |
335 queryStr = """ |
340 queryStr = """ |
336 DELETE FROM hash_prefix |
341 DELETE FROM hash_prefix |
337 WHERE threat_type=? AND platform_type=? AND threat_entry_type=? |
342 WHERE threat_type=? AND platform_type=? AND threat_entry_type=? |
338 """ |
343 """ |
339 |
344 |
340 db = QSqlDatabase.database(self.__connectionName) |
345 db = QSqlDatabase.database(self.__connectionName) |
341 if db.isOpen(): |
346 if db.isOpen(): |
342 db.transaction() |
347 db.transaction() |
343 try: |
348 try: |
344 query = QSqlQuery(db) |
349 query = QSqlQuery(db) |
345 query.prepare(queryStr) |
350 query.prepare(queryStr) |
346 query.addBindValue(threatList.threatType) |
351 query.addBindValue(threatList.threatType) |
347 query.addBindValue(threatList.platformType) |
352 query.addBindValue(threatList.platformType) |
348 query.addBindValue(threatList.threatEntryType) |
353 query.addBindValue(threatList.threatEntryType) |
349 query.exec() |
354 query.exec() |
350 del query |
355 del query |
351 finally: |
356 finally: |
352 db.commit() |
357 db.commit() |
353 |
358 |
354 def cleanupFullHashes(self, keepExpiredFor=43200): |
359 def cleanupFullHashes(self, keepExpiredFor=43200): |
355 """ |
360 """ |
356 Public method to clean up full hash entries expired more than the |
361 Public method to clean up full hash entries expired more than the |
357 given time. |
362 given time. |
358 |
363 |
359 @param keepExpiredFor time period in seconds of entries to be expired |
364 @param keepExpiredFor time period in seconds of entries to be expired |
360 @type int or float |
365 @type int or float |
361 """ |
366 """ |
362 queryStr = ( |
367 queryStr = """ |
363 """ |
|
364 DELETE FROM full_hash |
368 DELETE FROM full_hash |
365 WHERE expires_at=datetime(current_timestamp, '{0} SECONDS') |
369 WHERE expires_at=datetime(current_timestamp, '{0} SECONDS') |
366 """.format(int(keepExpiredFor)) |
370 """.format( |
|
371 int(keepExpiredFor) |
367 ) |
372 ) |
368 |
373 |
369 db = QSqlDatabase.database(self.__connectionName) |
374 db = QSqlDatabase.database(self.__connectionName) |
370 if db.isOpen(): |
375 if db.isOpen(): |
371 db.transaction() |
376 db.transaction() |
372 try: |
377 try: |
373 query = QSqlQuery(db) |
378 query = QSqlQuery(db) |
374 query.prepare(queryStr) |
379 query.prepare(queryStr) |
375 query.exec() |
380 query.exec() |
376 del query |
381 del query |
377 finally: |
382 finally: |
378 db.commit() |
383 db.commit() |
379 |
384 |
380 def updateHashPrefixExpiration(self, threatList, hashPrefix, |
385 def updateHashPrefixExpiration(self, threatList, hashPrefix, negativeCacheDuration): |
381 negativeCacheDuration): |
|
382 """ |
386 """ |
383 Public method to update the hash prefix expiration time. |
387 Public method to update the hash prefix expiration time. |
384 |
388 |
385 @param threatList threat list info object |
389 @param threatList threat list info object |
386 @type ThreatList |
390 @type ThreatList |
387 @param hashPrefix hash prefix |
391 @param hashPrefix hash prefix |
388 @type bytes |
392 @type bytes |
389 @param negativeCacheDuration time in seconds the entry should remain |
393 @param negativeCacheDuration time in seconds the entry should remain |
390 in the cache |
394 in the cache |
391 @type int or float |
395 @type int or float |
392 """ |
396 """ |
393 queryStr = ( |
397 queryStr = """ |
394 """ |
|
395 UPDATE hash_prefix |
398 UPDATE hash_prefix |
396 SET negative_expires_at=datetime(current_timestamp, '+{0} SECONDS') |
399 SET negative_expires_at=datetime(current_timestamp, '+{0} SECONDS') |
397 WHERE value=? AND threat_type=? AND platform_type=? AND |
400 WHERE value=? AND threat_type=? AND platform_type=? AND |
398 threat_entry_type=? |
401 threat_entry_type=? |
399 """.format(int(negativeCacheDuration)) |
402 """.format( |
|
403 int(negativeCacheDuration) |
400 ) |
404 ) |
401 |
405 |
402 db = QSqlDatabase.database(self.__connectionName) |
406 db = QSqlDatabase.database(self.__connectionName) |
403 if db.isOpen(): |
407 if db.isOpen(): |
404 db.transaction() |
408 db.transaction() |
405 try: |
409 try: |
406 query = QSqlQuery(db) |
410 query = QSqlQuery(db) |
407 query.prepare(queryStr) |
411 query.prepare(queryStr) |
408 query.addBindValue( |
412 query.addBindValue( |
409 QByteArray(hashPrefix), |
413 QByteArray(hashPrefix), |
410 QSql.ParamTypeFlag.In | QSql.ParamTypeFlag.Binary) |
414 QSql.ParamTypeFlag.In | QSql.ParamTypeFlag.Binary, |
411 query.addBindValue(threatList.threatType) |
415 ) |
412 query.addBindValue(threatList.platformType) |
416 query.addBindValue(threatList.threatType) |
413 query.addBindValue(threatList.threatEntryType) |
417 query.addBindValue(threatList.platformType) |
414 query.exec() |
418 query.addBindValue(threatList.threatEntryType) |
415 del query |
419 query.exec() |
416 finally: |
420 del query |
417 db.commit() |
421 finally: |
418 |
422 db.commit() |
|
423 |
419 def getThreatLists(self): |
424 def getThreatLists(self): |
420 """ |
425 """ |
421 Public method to get the available threat lists. |
426 Public method to get the available threat lists. |
422 |
427 |
423 @return list of available threat lists |
428 @return list of available threat lists |
424 @rtype list of tuples of (ThreatList, str) |
429 @rtype list of tuples of (ThreatList, str) |
425 """ |
430 """ |
426 queryStr = """ |
431 queryStr = """ |
427 SELECT threat_type,platform_type,threat_entry_type,client_state |
432 SELECT threat_type,platform_type,threat_entry_type,client_state |
428 FROM threat_list |
433 FROM threat_list |
429 """ |
434 """ |
430 output = [] |
435 output = [] |
431 |
436 |
432 db = QSqlDatabase.database(self.__connectionName) |
437 db = QSqlDatabase.database(self.__connectionName) |
433 if db.isOpen(): |
438 if db.isOpen(): |
434 db.transaction() |
439 db.transaction() |
435 try: |
440 try: |
436 query = QSqlQuery(db) |
441 query = QSqlQuery(db) |
437 query.prepare(queryStr) |
442 query.prepare(queryStr) |
438 |
443 |
439 query.exec() |
444 query.exec() |
440 |
445 |
441 while query.next(): # __IGNORE_WARNING_M523__ |
446 while query.next(): # __IGNORE_WARNING_M523__ |
442 threatType = query.value(0) |
447 threatType = query.value(0) |
443 platformType = query.value(1) |
448 platformType = query.value(1) |
444 threatEntryType = query.value(2) |
449 threatEntryType = query.value(2) |
445 clientState = query.value(3) |
450 clientState = query.value(3) |
446 threatList = ThreatList(threatType, platformType, |
451 threatList = ThreatList(threatType, platformType, threatEntryType) |
447 threatEntryType) |
|
448 output.append((threatList, clientState)) |
452 output.append((threatList, clientState)) |
449 QCoreApplication.processEvents( |
453 QCoreApplication.processEvents( |
450 QEventLoop.ProcessEventsFlag.AllEvents, |
454 QEventLoop.ProcessEventsFlag.AllEvents, |
451 self.maxProcessEventsTime) |
455 self.maxProcessEventsTime, |
452 del query |
456 ) |
453 finally: |
457 del query |
454 db.commit() |
458 finally: |
455 |
459 db.commit() |
|
460 |
456 return output |
461 return output |
457 |
462 |
458 def addThreatList(self, threatList): |
463 def addThreatList(self, threatList): |
459 """ |
464 """ |
460 Public method to add a threat list to the cache. |
465 Public method to add a threat list to the cache. |
461 |
466 |
462 @param threatList threat list to be added |
467 @param threatList threat list to be added |
463 @type ThreatList |
468 @type ThreatList |
464 """ |
469 """ |
465 queryStr = """ |
470 queryStr = """ |
466 INSERT OR IGNORE INTO threat_list |
471 INSERT OR IGNORE INTO threat_list |
467 (threat_type, platform_type, threat_entry_type, timestamp) |
472 (threat_type, platform_type, threat_entry_type, timestamp) |
468 VALUES (?, ?, ?, current_timestamp) |
473 VALUES (?, ?, ?, current_timestamp) |
469 """ |
474 """ |
470 |
475 |
471 db = QSqlDatabase.database(self.__connectionName) |
476 db = QSqlDatabase.database(self.__connectionName) |
472 if db.isOpen(): |
477 if db.isOpen(): |
473 db.transaction() |
478 db.transaction() |
474 try: |
479 try: |
475 query = QSqlQuery(db) |
480 query = QSqlQuery(db) |
476 query.prepare(queryStr) |
481 query.prepare(queryStr) |
477 query.addBindValue(threatList.threatType) |
482 query.addBindValue(threatList.threatType) |
478 query.addBindValue(threatList.platformType) |
483 query.addBindValue(threatList.platformType) |
479 query.addBindValue(threatList.threatEntryType) |
484 query.addBindValue(threatList.threatEntryType) |
480 query.exec() |
485 query.exec() |
481 del query |
486 del query |
482 finally: |
487 finally: |
483 db.commit() |
488 db.commit() |
484 |
489 |
485 def deleteThreatList(self, threatList): |
490 def deleteThreatList(self, threatList): |
486 """ |
491 """ |
487 Public method to delete a threat list from the cache. |
492 Public method to delete a threat list from the cache. |
488 |
493 |
489 @param threatList threat list to be deleted |
494 @param threatList threat list to be deleted |
490 @type ThreatList |
495 @type ThreatList |
491 """ |
496 """ |
492 queryStr = """ |
497 queryStr = """ |
493 DELETE FROM threat_list |
498 DELETE FROM threat_list |
494 WHERE threat_type=? AND platform_type=? AND threat_entry_type=? |
499 WHERE threat_type=? AND platform_type=? AND threat_entry_type=? |
495 """ |
500 """ |
496 |
501 |
497 db = QSqlDatabase.database(self.__connectionName) |
502 db = QSqlDatabase.database(self.__connectionName) |
498 if db.isOpen(): |
503 if db.isOpen(): |
499 db.transaction() |
504 db.transaction() |
500 try: |
505 try: |
501 query = QSqlQuery(db) |
506 query = QSqlQuery(db) |
502 query.prepare(queryStr) |
507 query.prepare(queryStr) |
503 query.addBindValue(threatList.threatType) |
508 query.addBindValue(threatList.threatType) |
504 query.addBindValue(threatList.platformType) |
509 query.addBindValue(threatList.platformType) |
505 query.addBindValue(threatList.threatEntryType) |
510 query.addBindValue(threatList.threatEntryType) |
506 query.exec() |
511 query.exec() |
507 del query |
512 del query |
508 finally: |
513 finally: |
509 db.commit() |
514 db.commit() |
510 |
515 |
511 def updateThreatListClientState(self, threatList, clientState): |
516 def updateThreatListClientState(self, threatList, clientState): |
512 """ |
517 """ |
513 Public method to update the client state of a threat list. |
518 Public method to update the client state of a threat list. |
514 |
519 |
515 @param threatList threat list to update the client state for |
520 @param threatList threat list to update the client state for |
516 @type ThreatList |
521 @type ThreatList |
517 @param clientState new client state |
522 @param clientState new client state |
518 @type str |
523 @type str |
519 """ |
524 """ |
520 queryStr = """ |
525 queryStr = """ |
521 UPDATE threat_list SET timestamp=current_timestamp, client_state=? |
526 UPDATE threat_list SET timestamp=current_timestamp, client_state=? |
522 WHERE threat_type=? AND platform_type=? AND threat_entry_type=? |
527 WHERE threat_type=? AND platform_type=? AND threat_entry_type=? |
523 """ |
528 """ |
524 |
529 |
525 db = QSqlDatabase.database(self.__connectionName) |
530 db = QSqlDatabase.database(self.__connectionName) |
526 if db.isOpen(): |
531 if db.isOpen(): |
527 db.transaction() |
532 db.transaction() |
528 try: |
533 try: |
529 query = QSqlQuery(db) |
534 query = QSqlQuery(db) |
594 INSERT INTO hash_prefix |
599 INSERT INTO hash_prefix |
595 (value, cue, threat_type, platform_type, threat_entry_type, |
600 (value, cue, threat_type, platform_type, threat_entry_type, |
596 timestamp) |
601 timestamp) |
597 VALUES (?, ?, ?, ?, ?, current_timestamp) |
602 VALUES (?, ?, ?, ?, ?, current_timestamp) |
598 """ |
603 """ |
599 |
604 |
600 db = QSqlDatabase.database(self.__connectionName) |
605 db = QSqlDatabase.database(self.__connectionName) |
601 if db.isOpen(): |
606 if db.isOpen(): |
602 db.transaction() |
607 db.transaction() |
603 try: |
608 try: |
604 for prefix in prefixes: |
609 for prefix in prefixes: |
605 query = QSqlQuery(db) |
610 query = QSqlQuery(db) |
606 query.prepare(queryStr) |
611 query.prepare(queryStr) |
607 query.addBindValue( |
612 query.addBindValue( |
608 QByteArray(prefix), |
613 QByteArray(prefix), |
609 QSql.ParamTypeFlag.In | QSql.ParamTypeFlag.Binary) |
614 QSql.ParamTypeFlag.In | QSql.ParamTypeFlag.Binary, |
|
615 ) |
610 query.addBindValue(prefix[:4].hex()) |
616 query.addBindValue(prefix[:4].hex()) |
611 query.addBindValue(threatList.threatType) |
617 query.addBindValue(threatList.threatType) |
612 query.addBindValue(threatList.platformType) |
618 query.addBindValue(threatList.platformType) |
613 query.addBindValue(threatList.threatEntryType) |
619 query.addBindValue(threatList.threatEntryType) |
614 query.exec() |
620 query.exec() |
615 del query |
621 del query |
616 QCoreApplication.processEvents( |
622 QCoreApplication.processEvents( |
617 QEventLoop.ProcessEventsFlag.AllEvents, |
623 QEventLoop.ProcessEventsFlag.AllEvents, |
618 self.maxProcessEventsTime) |
624 self.maxProcessEventsTime, |
619 finally: |
625 ) |
620 db.commit() |
626 finally: |
621 |
627 db.commit() |
|
628 |
622 def getHashPrefixValuesToRemove(self, threatList, indexes): |
629 def getHashPrefixValuesToRemove(self, threatList, indexes): |
623 """ |
630 """ |
624 Public method to get the hash prefix values to be removed from the |
631 Public method to get the hash prefix values to be removed from the |
625 cache. |
632 cache. |
626 |
633 |
627 @param threatList threat list to remove prefixes from |
634 @param threatList threat list to remove prefixes from |
628 @type ThreatList |
635 @type ThreatList |
629 @param indexes list of indexes of prefixes to be removed |
636 @param indexes list of indexes of prefixes to be removed |
630 @type list of int |
637 @type list of int |
631 @return list of hash prefixes to be removed |
638 @return list of hash prefixes to be removed |
636 WHERE threat_type=? AND platform_type=? AND threat_entry_type=? |
643 WHERE threat_type=? AND platform_type=? AND threat_entry_type=? |
637 ORDER BY value |
644 ORDER BY value |
638 """ |
645 """ |
639 indexes = set(indexes) |
646 indexes = set(indexes) |
640 output = [] |
647 output = [] |
641 |
648 |
642 db = QSqlDatabase.database(self.__connectionName) |
649 db = QSqlDatabase.database(self.__connectionName) |
643 if db.isOpen(): |
650 if db.isOpen(): |
644 db.transaction() |
651 db.transaction() |
645 try: |
652 try: |
646 query = QSqlQuery(db) |
653 query = QSqlQuery(db) |
647 query.prepare(queryStr) |
654 query.prepare(queryStr) |
648 query.addBindValue(threatList.threatType) |
655 query.addBindValue(threatList.threatType) |
649 query.addBindValue(threatList.platformType) |
656 query.addBindValue(threatList.platformType) |
650 query.addBindValue(threatList.threatEntryType) |
657 query.addBindValue(threatList.threatEntryType) |
651 |
658 |
652 query.exec() |
659 query.exec() |
653 |
660 |
654 index = 0 |
661 index = 0 |
655 while query.next(): # __IGNORE_WARNING_M523__ |
662 while query.next(): # __IGNORE_WARNING_M523__ |
656 if index in indexes: |
663 if index in indexes: |
657 prefix = bytes(query.value(0)) |
664 prefix = bytes(query.value(0)) |
658 output.append(prefix) |
665 output.append(prefix) |
659 index += 1 |
666 index += 1 |
660 QCoreApplication.processEvents( |
667 QCoreApplication.processEvents( |
661 QEventLoop.ProcessEventsFlag.AllEvents, |
668 QEventLoop.ProcessEventsFlag.AllEvents, |
662 self.maxProcessEventsTime) |
669 self.maxProcessEventsTime, |
663 del query |
670 ) |
664 finally: |
671 del query |
665 db.commit() |
672 finally: |
666 |
673 db.commit() |
|
674 |
667 return output |
675 return output |
668 |
676 |
669 def removeHashPrefixIndices(self, threatList, indexes): |
677 def removeHashPrefixIndices(self, threatList, indexes): |
670 """ |
678 """ |
671 Public method to remove hash prefixes from the cache. |
679 Public method to remove hash prefixes from the cache. |
672 |
680 |
673 @param threatList threat list to delete hash prefixes of |
681 @param threatList threat list to delete hash prefixes of |
674 @type ThreatList |
682 @type ThreatList |
675 @param indexes list of indexes of prefixes to be removed |
683 @param indexes list of indexes of prefixes to be removed |
676 @type list of int |
684 @type list of int |
677 """ |
685 """ |
678 queryStr = ( |
686 queryStr = """ |
679 """ |
|
680 DELETE FROM hash_prefix |
687 DELETE FROM hash_prefix |
681 WHERE threat_type=? AND platform_type=? AND |
688 WHERE threat_type=? AND platform_type=? AND |
682 threat_entry_type=? AND value IN ({0}) |
689 threat_entry_type=? AND value IN ({0}) |
683 """ |
690 """ |
684 ) |
|
685 batchSize = 40 |
691 batchSize = 40 |
686 |
692 |
687 prefixesToRemove = self.getHashPrefixValuesToRemove( |
693 prefixesToRemove = self.getHashPrefixValuesToRemove(threatList, indexes) |
688 threatList, indexes) |
|
689 if prefixesToRemove: |
694 if prefixesToRemove: |
690 db = QSqlDatabase.database(self.__connectionName) |
695 db = QSqlDatabase.database(self.__connectionName) |
691 if db.isOpen(): |
696 if db.isOpen(): |
692 db.transaction() |
697 db.transaction() |
693 try: |
698 try: |
694 for index in range(0, len(prefixesToRemove), batchSize): |
699 for index in range(0, len(prefixesToRemove), batchSize): |
695 removeBatch = prefixesToRemove[ |
700 removeBatch = prefixesToRemove[index : (index + batchSize)] |
696 index:(index + batchSize) |
701 |
697 ] |
|
698 |
|
699 query = QSqlQuery(db) |
702 query = QSqlQuery(db) |
700 query.prepare( |
703 query.prepare( |
701 queryStr.format(",".join(["?"] * len(removeBatch))) |
704 queryStr.format(",".join(["?"] * len(removeBatch))) |
702 ) |
705 ) |
703 query.addBindValue(threatList.threatType) |
706 query.addBindValue(threatList.threatType) |
704 query.addBindValue(threatList.platformType) |
707 query.addBindValue(threatList.platformType) |
705 query.addBindValue(threatList.threatEntryType) |
708 query.addBindValue(threatList.threatEntryType) |
706 for prefix in removeBatch: |
709 for prefix in removeBatch: |
707 query.addBindValue( |
710 query.addBindValue( |
708 QByteArray(prefix), |
711 QByteArray(prefix), |
709 QSql.ParamTypeFlag.In | |
712 QSql.ParamTypeFlag.In | QSql.ParamTypeFlag.Binary, |
710 QSql.ParamTypeFlag.Binary) |
713 ) |
711 query.exec() |
714 query.exec() |
712 del query |
715 del query |
713 QCoreApplication.processEvents( |
716 QCoreApplication.processEvents( |
714 QEventLoop.ProcessEventsFlag.AllEvents, |
717 QEventLoop.ProcessEventsFlag.AllEvents, |
715 self.maxProcessEventsTime) |
718 self.maxProcessEventsTime, |
|
719 ) |
716 finally: |
720 finally: |
717 db.commit() |
721 db.commit() |
718 |
722 |
|
723 |
719 # |
724 # |
720 # eflag: noqa = S608 |
725 # eflag: noqa = S608 |