175 |
176 |
176 def __setAutoUpdateThreatLists(self): |
177 def __setAutoUpdateThreatLists(self): |
177 """ |
178 """ |
178 Private method to set auto update for the threat lists. |
179 Private method to set auto update for the threat lists. |
179 """ |
180 """ |
180 autoUpdateEnabled = \ |
181 autoUpdateEnabled = ( |
181 Preferences.getWebBrowser("SafeBrowsingAutoUpdate") and \ |
182 Preferences.getWebBrowser("SafeBrowsingAutoUpdate") and |
182 not Preferences.getWebBrowser("SafeBrowsingUseLookupApi") |
183 not Preferences.getWebBrowser("SafeBrowsingUseLookupApi") |
|
184 ) |
183 if autoUpdateEnabled and self.isEnabled(): |
185 if autoUpdateEnabled and self.isEnabled(): |
184 nextUpdateDateTime = Preferences.getWebBrowser( |
186 nextUpdateDateTime = Preferences.getWebBrowser( |
185 "SafeBrowsingUpdateDateTime") |
187 "SafeBrowsingUpdateDateTime") |
186 if nextUpdateDateTime.isValid(): |
188 if nextUpdateDateTime.isValid(): |
187 interval = \ |
189 interval = ( |
188 QDateTime.currentDateTime().secsTo(nextUpdateDateTime) + 2 |
190 QDateTime.currentDateTime().secsTo(nextUpdateDateTime) + 2 |
189 # 2 seconds extra wait time; interval in milliseconds |
191 # 2 seconds extra wait time; interval in milliseconds |
|
192 ) |
190 |
193 |
191 if interval < 5: |
194 if interval < 5: |
192 interval = 5 |
195 interval = 5 |
193 # minimum 5 seconds interval |
196 # minimum 5 seconds interval |
194 else: |
197 else: |
215 else: |
218 else: |
216 self.__showNotificationMessage( |
219 self.__showNotificationMessage( |
217 self.tr("Updating threat lists failed")) |
220 self.tr("Updating threat lists failed")) |
218 |
221 |
219 if ok: |
222 if ok: |
220 nextUpdateDateTime = \ |
223 nextUpdateDateTime = ( |
221 self.__apiClient.getFairUseDelayExpirationDateTime() |
224 self.__apiClient.getFairUseDelayExpirationDateTime() |
|
225 ) |
222 Preferences.setWebBrowser("SafeBrowsingUpdateDateTime", |
226 Preferences.setWebBrowser("SafeBrowsingUpdateDateTime", |
223 nextUpdateDateTime) |
227 nextUpdateDateTime) |
224 self.__threatListsUpdateTimer.start( |
228 self.__threatListsUpdateTimer.start( |
225 (QDateTime.currentDateTime().secsTo(nextUpdateDateTime) + 2) * |
229 (QDateTime.currentDateTime().secsTo(nextUpdateDateTime) + 2) * |
226 1000) |
230 1000) |
238 """ |
242 """ |
239 if not self.isEnabled(): |
243 if not self.isEnabled(): |
240 return False, self.tr("Safe Browsing is disabled.") |
244 return False, self.tr("Safe Browsing is disabled.") |
241 |
245 |
242 if not self.__apiClient.fairUseDelayExpired(): |
246 if not self.__apiClient.fairUseDelayExpired(): |
243 return False, \ |
247 return ( |
|
248 False, |
244 self.tr("The fair use wait period has not expired yet." |
249 self.tr("The fair use wait period has not expired yet." |
245 "Expiration will be at {0}.").format( |
250 "Expiration will be at {0}.").format( |
246 self.__apiClient.getFairUseDelayExpirationDateTime() |
251 self.__apiClient.getFairUseDelayExpirationDateTime() |
247 .toString("yyyy-MM-dd, HH:mm:ss")) |
252 .toString("yyyy-MM-dd, HH:mm:ss")) |
|
253 ) |
248 |
254 |
249 self.__updatingThreatLists = True |
255 self.__updatingThreatLists = True |
250 ok = True |
256 ok = True |
251 errorMessage = "" |
257 errorMessage = "" |
252 |
258 |
268 for entry in threatLists: |
274 for entry in threatLists: |
269 current += 1 |
275 current += 1 |
270 self.progress.emit(current) |
276 self.progress.emit(current) |
271 QCoreApplication.processEvents() |
277 QCoreApplication.processEvents() |
272 threatList = ThreatList.fromApiEntry(entry) |
278 threatList = ThreatList.fromApiEntry(entry) |
273 if self.__platforms is None or \ |
279 if ( |
274 threatList.platformType in self.__platforms: |
280 self.__platforms is None or |
|
281 threatList.platformType in self.__platforms |
|
282 ): |
275 self.__cache.addThreatList(threatList) |
283 self.__cache.addThreatList(threatList) |
276 key = repr(threatList) |
284 key = repr(threatList) |
277 if key in threatListsForRemove: |
285 if key in threatListsForRemove: |
278 del threatListsForRemove[key] |
286 del threatListsForRemove[key] |
279 maximum = len(threatListsForRemove.values()) |
287 maximum = len(threatListsForRemove.values()) |
291 # step 3: update threats |
299 # step 3: update threats |
292 threatLists = self.__cache.getThreatLists() |
300 threatLists = self.__cache.getThreatLists() |
293 clientStates = {} |
301 clientStates = {} |
294 for threatList, clientState in threatLists: |
302 for threatList, clientState in threatLists: |
295 clientStates[threatList.asTuple()] = clientState |
303 clientStates[threatList.asTuple()] = clientState |
296 threatsUpdateResponses, error = \ |
304 threatsUpdateResponses, error = self.__apiClient.getThreatsUpdate( |
297 self.__apiClient.getThreatsUpdate(clientStates) |
305 clientStates) |
298 if error: |
306 if error: |
299 return False, error |
307 return False, error |
300 |
308 |
301 maximum = len(threatsUpdateResponses) |
309 maximum = len(threatsUpdateResponses) |
302 current = 0 |
310 current = 0 |
394 url = QUrl(url.strip()) |
402 url = QUrl(url.strip()) |
395 |
403 |
396 if url.isEmpty(): |
404 if url.isEmpty(): |
397 raise ValueError("Empty URL given.") |
405 raise ValueError("Empty URL given.") |
398 |
406 |
399 listNames, error = \ |
407 listNames, error = self.__apiClient.lookupUrl( |
400 self.__apiClient.lookupUrl(url, self.__platforms) |
408 url, self.__platforms) |
401 return listNames, error |
409 return listNames, error |
402 else: |
410 else: |
403 if isinstance(url, QUrl): |
411 if isinstance(url, QUrl): |
404 urlStr = url.toString().strip() |
412 urlStr = url.toString().strip() |
405 else: |
413 else: |
430 |
438 |
431 matchingPrefixes = {} |
439 matchingPrefixes = {} |
432 matchingFullHashes = set() |
440 matchingFullHashes = set() |
433 isPotentialThreat = False |
441 isPotentialThreat = False |
434 # Lookup hash prefixes which match full URL hash |
442 # Lookup hash prefixes which match full URL hash |
435 for _threatList, hashPrefix, negativeCacheExpired in \ |
443 for _threatList, hashPrefix, negativeCacheExpired in ( |
436 self.__cache.lookupHashPrefix(cues): |
444 self.__cache.lookupHashPrefix(cues) |
|
445 ): |
437 for fullHash in fullHashes: |
446 for fullHash in fullHashes: |
438 if fullHash.startswith(hashPrefix): |
447 if fullHash.startswith(hashPrefix): |
439 isPotentialThreat = True |
448 isPotentialThreat = True |
440 # consider hash prefix negative cache as expired if it |
449 # consider hash prefix negative cache as expired if it |
441 # is expired in at least one threat list |
450 # is expired in at least one threat list |
458 if result: |
467 if result: |
459 return result |
468 return result |
460 |
469 |
461 # If there are no matching expired full hash entries and negative |
470 # If there are no matching expired full hash entries and negative |
462 # cache is still current for all prefixes, consider it safe. |
471 # cache is still current for all prefixes, consider it safe. |
463 if len(matchingExpiredThreatLists) == 0 and \ |
472 if ( |
464 sum(map(int, matchingPrefixes.values())) == 0: |
473 len(matchingExpiredThreatLists) == 0 and |
|
474 sum(map(int, matchingPrefixes.values())) == 0 |
|
475 ): |
465 return [] |
476 return [] |
466 |
477 |
467 # Now it can be assumed that there are expired matching full hash |
478 # Now it can be assumed that there are expired matching full hash |
468 # entries and/or cache prefix entries with expired negative cache. |
479 # entries and/or cache prefix entries with expired negative cache. |
469 # Both require full hash synchronization. |
480 # Both require full hash synchronization. |