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 11 12class Blacklist(object): 13 14 def __init__(self, path): 15 self._blacklist_lock = threading.RLock() 16 self._path = path 17 18 def Read(self): 19 """Reads the blacklist from the blacklist file. 20 21 Returns: 22 A dict containing bad devices. 23 """ 24 with self._blacklist_lock: 25 if not os.path.exists(self._path): 26 return dict() 27 28 with open(self._path, 'r') as f: 29 blacklist = json.load(f) 30 if not isinstance(blacklist, dict): 31 logging.warning('Ignoring %s: %s (a dict was expected instead)', 32 self._path, blacklist) 33 blacklist = dict() 34 return blacklist 35 36 def Write(self, blacklist): 37 """Writes the provided blacklist to the blacklist file. 38 39 Args: 40 blacklist: list of bad devices to write to the blacklist file. 41 """ 42 with self._blacklist_lock: 43 with open(self._path, 'w') as f: 44 json.dump(blacklist, f) 45 46 def Extend(self, devices, reason='unknown'): 47 """Adds devices to blacklist file. 48 49 Args: 50 devices: list of bad devices to be added to the blacklist file. 51 reason: string specifying the reason for blacklist (eg: 'unauthorized') 52 """ 53 timestamp = time.time() 54 event_info = { 55 'timestamp': timestamp, 56 'reason': reason, 57 } 58 device_dicts = {device: event_info for device in devices} 59 logging.info('Adding %s to blacklist %s for reason: %s', 60 ','.join(devices), self._path, reason) 61 with self._blacklist_lock: 62 blacklist = self.Read() 63 blacklist.update(device_dicts) 64 self.Write(blacklist) 65 66 def Reset(self): 67 """Erases the blacklist file if it exists.""" 68 logging.info('Resetting blacklist %s', self._path) 69 with self._blacklist_lock: 70 if os.path.exists(self._path): 71 os.remove(self._path) 72