1# Copyright 2014 The Chromium Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5import json 6import logging 7import os 8import threading 9import time 10 11logger = logging.getLogger(__name__) 12 13 14class Blacklist(object): 15 16 def __init__(self, path): 17 self._blacklist_lock = threading.RLock() 18 self._path = path 19 20 def Read(self): 21 """Reads the blacklist from the blacklist file. 22 23 Returns: 24 A dict containing bad devices. 25 """ 26 with self._blacklist_lock: 27 blacklist = dict() 28 if not os.path.exists(self._path): 29 return blacklist 30 31 try: 32 with open(self._path, 'r') as f: 33 blacklist = json.load(f) 34 except (IOError, ValueError) as e: 35 logger.warning('Unable to read blacklist: %s', str(e)) 36 os.remove(self._path) 37 38 if not isinstance(blacklist, dict): 39 logger.warning('Ignoring %s: %s (a dict was expected instead)', 40 self._path, blacklist) 41 blacklist = dict() 42 43 return blacklist 44 45 def Write(self, blacklist): 46 """Writes the provided blacklist to the blacklist file. 47 48 Args: 49 blacklist: list of bad devices to write to the blacklist file. 50 """ 51 with self._blacklist_lock: 52 with open(self._path, 'w') as f: 53 json.dump(blacklist, f) 54 55 def Extend(self, devices, reason='unknown'): 56 """Adds devices to blacklist file. 57 58 Args: 59 devices: list of bad devices to be added to the blacklist file. 60 reason: string specifying the reason for blacklist (eg: 'unauthorized') 61 """ 62 timestamp = time.time() 63 event_info = { 64 'timestamp': timestamp, 65 'reason': reason, 66 } 67 device_dicts = {device: event_info for device in devices} 68 logger.info('Adding %s to blacklist %s for reason: %s', 69 ','.join(devices), self._path, reason) 70 with self._blacklist_lock: 71 blacklist = self.Read() 72 blacklist.update(device_dicts) 73 self.Write(blacklist) 74 75 def Reset(self): 76 """Erases the blacklist file if it exists.""" 77 logger.info('Resetting blacklist %s', self._path) 78 with self._blacklist_lock: 79 if os.path.exists(self._path): 80 os.remove(self._path) 81