def __init__(self, config): super(Dispatcher, self).__init__(config) self.authorized = False self.load_config_object('badge_reader', on_scan=self.badge_scan) self.load_config_object('enable_output') self.load_config_object('buzzer') self.door_timer = Timer(self.event_queue, 'door_timer', self.abort) self.noise = None self.threads.extend([self.door_timer])
def __init__(self, config): super(Dispatcher, self).__init__(config) self.authorized = False self.load_config_object('on_button', on_down=self.on_button_down) self.load_config_object('off_button', on_down=self.abort) self.load_config_object('badge_reader', on_scan=self.badge_scan) self.load_config_object('enable_output') self.load_config_object('buzzer') self.warning_timer = Timer(self.event_queue, 'warning_timer', self.warning) self.expire_timer = Timer(self.event_queue, 'expire_timer', self.abort) self.expecting_press_timer = Timer(self.event_queue, 'expecting_press_timer', self.abort) # Otherwise, start them manually! self.threads.extend([self.warning_timer, self.expire_timer, self.expecting_press_timer]) self.noise = None
def __init__(self, config): super(Dispatcher, self).__init__(config) for i in range(1, 6 + 1): self.load_config_object('j%d' % i, on_down=self.on_button_down) self.load_config_object('buzzer') self.load_config_object('relays') # This may be a MultiProxy, which makes this easier. self.relays.on() self.relay_value = True # Run fans for 10 seconds on startup self.relay_timer = Timer(self.event_queue, 'relay_timer', self.toggle_relays) self.relay_toggle_interval = 10 self.relay_timer.set(self.relay_toggle_interval) self.threads.extend([self.relay_timer])
class Dispatcher(BaseDispatcher): def __init__(self, config): super(Dispatcher, self).__init__(config) self.load_config_object('j1', on_down=self.on_button_down) self.load_config_object('badge_reader', on_scan=self.badge_scan) self.load_config_object('buzzer') self.load_config_object('relays') # This may be a MultiProxy, which makes this easier. self.relays.on() self.relay_value = True # Run fans for 10 seconds on startup self.relay_timer = Timer(self.event_queue, 'relay_timer', self.toggle_relays) self.relay_toggle_interval = 10 self.relay_timer.set(self.relay_toggle_interval) self.threads.extend([self.relay_timer]) def on_button_down(self, source): print "Button down", source self.buzzer.beep() source.on() time.sleep(0.3) source.off() def badge_scan(self, badge_id): print "Badge ID", badge_id def toggle_relays(self, source): print "Toggle relay", self.relay_value if self.relay_value: self.relays.off() self.relay_value = False else: self.relays.on() self.relay_value = True self.relay_timer.set(self.relay_toggle_interval)
class Dispatcher(BaseDispatcher): def __init__(self, config): super(Dispatcher, self).__init__(config) for i in range(1, 6+1): self.load_config_object('j%d' % i, on_down=self.on_button_down) self.load_config_object('buzzer') self.load_config_object('relays') # This may be a MultiProxy, which makes this easier. self.relays.on() self.relay_value = True # Run fans for 10 seconds on startup self.relay_timer = Timer(self.event_queue, 'relay_timer', self.toggle_relays) self.relay_toggle_interval = 10 self.relay_timer.set(self.relay_toggle_interval) self.threads.extend([self.relay_timer]) def on_button_down(self, source): print "Button down", source self.buzzer.beep() source.on() time.sleep(0.3) source.off() def toggle_relays(self, source): print "Toggle relay", self.relay_value if self.relay_value: self.relays.off() self.relay_value = False else: self.relays.on() self.relay_value = True self.relay_timer.set(self.relay_toggle_interval)
def __init__(self, config): super(Dispatcher, self).__init__(config) for i in range(1, 6+1): self.load_config_object('j%d' % i, on_down=self.on_button_down) self.load_config_object('buzzer') self.load_config_object('relays') # This may be a MultiProxy, which makes this easier. self.relays.on() self.relay_value = True # Run fans for 10 seconds on startup self.relay_timer = Timer(self.event_queue, 'relay_timer', self.toggle_relays) self.relay_toggle_interval = 10 self.relay_timer.set(self.relay_toggle_interval) self.threads.extend([self.relay_timer])
def __init__(self, config): super(Dispatcher, self).__init__(config) self.authorized = False self.load_config_object('on_button', on_down=self.on_button_down) self.load_config_object('off_button', on_down=self.abort) self.load_config_object('badge_reader', on_scan=self.badge_scan) self.load_config_object('enable_output') self.load_config_object('buzzer') self.warning_timer = Timer(self.event_queue, 'warning_timer', self.warning) self.expire_timer = Timer(self.event_queue, 'expire_timer', self.abort) self.expecting_press_timer = Timer(self.event_queue, 'expecting_press_timer', self.abort) # Otherwise, start them manually! self.threads.extend([ self.warning_timer, self.expire_timer, self.expecting_press_timer ]) self.noise = None
class Dispatcher(BaseDispatcher): def __init__(self, config): super(Dispatcher, self).__init__(config) self.authorized = False self.load_config_object('on_button', on_down=self.on_button_down) self.load_config_object('off_button', on_down=self.abort) self.load_config_object('badge_reader', on_scan=self.badge_scan) self.load_config_object('enable_output') self.load_config_object('buzzer') self.warning_timer = Timer(self.event_queue, 'warning_timer', self.warning) self.expire_timer = Timer(self.event_queue, 'expire_timer', self.abort) self.expecting_press_timer = Timer(self.event_queue, 'expecting_press_timer', self.abort) # Otherwise, start them manually! self.threads.extend([ self.warning_timer, self.expire_timer, self.expecting_press_timer ]) self.noise = None def _get_command_line(self, section, key, format_args): """Constructs a command line, safely. The value can contain {key}, {}, and {5} style interpolation: - {key} will be resolved in the config.get; those are considered safe and spaces will separate args. - {} works on each arg independently (probably not what you want). - {5} works fine. """ value = self.config.get(section, key) pieces = shlex.split(value) return [p.format(*format_args) for p in pieces] def badge_scan(self, badge_id): # Malicious badge "numbers" that contain spaces require this extra work. command = self._get_command_line('auth', 'command', [badge_id]) # TODO timeout # TODO test with missing command rc = subprocess.call(command) if rc == 0: self.buzzer.beep() self.authorized = True self.badge_id = badge_id self.expecting_press_timer.set(30) self.on_button.blink() else: self.buzzer.beep() if self.noise: self.noise.kill() if self.config.get('sounds', 'enable') == '1': sound_command = self._get_command_line( 'sounds', 'command', [self.config.get('sounds', 'sad_filename')]) self.noise = subprocess.Popen(sound_command, stdin=DEVNULL, stdout=DEVNULL, stderr=DEVNULL) def on_button_down(self, source): print "Button down", source if not self.authorized: self.buzzer.beep() if self.noise: self.noise.kill() if self.config.get('sounds', 'enable') == '1': sound_command = self._get_command_line( 'sounds', 'command', [self.config.get('sounds', 'sad_filename')]) self.noise = subprocess.Popen(sound_command, stdin=DEVNULL, stdout=DEVNULL, stderr=DEVNULL) return self.expecting_press_timer.cancel() self.on_button.on() self.enable_output.on() self.buzzer.off() self.warning_timer.cancel() self.expire_timer.cancel() # TODO use extend time if we were already enabled, and run its command for # logging. # N.b. Duration (or extend) includes the warning time. self.warning_timer.set( self.config.get_int_seconds('auth', 'duration', '5m') - self.config.get_int_seconds('auth', 'warning', '10s')) self.expire_timer.set( self.config.get_int_seconds('auth', 'duration', '5m')) if self.noise: self.noise.kill() self.noise = None def abort(self, source): print "Abort", source if self.authorized: command = self._get_command_line('auth', 'deauth_command', [self.badge_id]) subprocess.call(command) self.authorized = False self.warning_timer.cancel() self.expecting_press_timer.cancel() self.on_button.off() self.enable_output.off() self.buzzer.off() if self.noise: self.noise.kill() self.noise = None def warning(self, unused_source): self.buzzer.beepbeep() if self.config.get('sounds', 'enable') == '1': sound_command = self._get_command_line( 'sounds', 'command', [self.config.get('sounds', 'warning_filename')]) self.noise = subprocess.Popen(shlex.split(sound_command), stdin=DEVNULL, stdout=DEVNULL, stderr=DEVNULL) self.on_button.blink()
class Dispatcher(BaseDispatcher): def __init__(self, config): super(Dispatcher, self).__init__(config) self.authorized = False self.load_config_object('on_button', on_down=self.on_button_down) self.load_config_object('off_button', on_down=self.abort) self.load_config_object('badge_reader', on_scan=self.badge_scan) self.load_config_object('enable_output') self.load_config_object('buzzer') self.warning_timer = Timer(self.event_queue, 'warning_timer', self.warning) self.expire_timer = Timer(self.event_queue, 'expire_timer', self.abort) self.expecting_press_timer = Timer(self.event_queue, 'expecting_press_timer', self.abort) # Otherwise, start them manually! self.threads.extend([self.warning_timer, self.expire_timer, self.expecting_press_timer]) self.noise = None def _get_command_line(self, section, key, format_args): """Constructs a command line, safely. The value can contain {key}, {}, and {5} style interpolation: - {key} will be resolved in the config.get; those are considered safe and spaces will separate args. - {} works on each arg independently (probably not what you want). - {5} works fine. """ value = self.config.get(section, key) pieces = shlex.split(value) return [p.format(*format_args) for p in pieces] def badge_scan(self, badge_id): # Malicious badge "numbers" that contain spaces require this extra work. command = self._get_command_line('auth', 'command', [badge_id]) # TODO timeout # TODO test with missing command rc = subprocess.call(command) if rc == 0: self.buzzer.beep() self.authorized = True self.badge_id = badge_id self.expecting_press_timer.set(30) self.on_button.blink() else: self.buzzer.beep() if self.noise: self.noise.kill() if self.config.get('sounds', 'enable') == '1': sound_command = self._get_command_line('sounds', 'command', [self.config.get('sounds', 'sad_filename')]) self.noise = subprocess.Popen(sound_command, stdin=DEVNULL, stdout=DEVNULL, stderr=DEVNULL) def on_button_down(self, source): print "Button down", source if not self.authorized: self.buzzer.beep() if self.noise: self.noise.kill() if self.config.get('sounds', 'enable') == '1': sound_command = self._get_command_line('sounds', 'command', [self.config.get('sounds', 'sad_filename')]) self.noise = subprocess.Popen(sound_command, stdin=DEVNULL, stdout=DEVNULL, stderr=DEVNULL) return self.expecting_press_timer.cancel() self.on_button.on() self.enable_output.on() self.buzzer.off() self.warning_timer.cancel() self.expire_timer.cancel() # TODO use extend time if we were already enabled, and run its command for # logging. # N.b. Duration (or extend) includes the warning time. self.warning_timer.set(self.config.get_int_seconds('auth', 'duration', '5m') - self.config.get_int_seconds('auth', 'warning', '10s')) self.expire_timer.set(self.config.get_int_seconds('auth', 'duration', '5m')) if self.noise: self.noise.kill() self.noise = None def abort(self, source): print "Abort", source if self.authorized: command = self._get_command_line('auth', 'deauth_command', [self.badge_id]) subprocess.call(command) self.authorized = False self.warning_timer.cancel() self.expecting_press_timer.cancel() self.on_button.off() self.enable_output.off() self.buzzer.off() if self.noise: self.noise.kill() self.noise = None def warning(self, unused_source): self.buzzer.beepbeep() if self.config.get('sounds', 'enable') == '1': sound_command = self._get_command_line('sounds', 'command', [self.config.get('sounds', 'warning_filename')]) self.noise = subprocess.Popen(shlex.split(sound_command), stdin=DEVNULL, stdout=DEVNULL, stderr=DEVNULL) self.on_button.blink()
class Dispatcher(BaseDispatcher): def __init__(self, config): super(Dispatcher, self).__init__(config) self.authorized = False self.load_config_object('badge_reader', on_scan=self.badge_scan) self.load_config_object('enable_output') self.load_config_object('buzzer') self.door_timer = Timer(self.event_queue, 'door_timer', self.abort) self.noise = None self.threads.extend([self.door_timer]) def _get_command_line(self, section, key, format_args): """Constructs a command line, safely. The value can contain {key}, {}, and {5} style interpolation: - {key} will be resolved in the config.get; those are considered safe and spaces will separate args. - {} works on each arg independently (probably not what you want). - {5} works fine. """ value = self.config.get(section, key) pieces = shlex.split(value) return [p.format(*format_args) for p in pieces] def badge_scan(self, badge_id): """Executes scanning of a users badge. Note: "command" below will execute a shell operation defined via the configuration option in authboxrc. This script should exit with a zero error code on a successful authorization and non-zero on a failure. Args: badge_id: The badge value as passed directly by the reader. """ print("Badge scanned - {}".format(badge_id)) try: # Malicious badge "numbers" that contain spaces require this extra work. command = self._get_command_line('auth', 'command', [badge_id]) rc = subprocess.call(command) except IOError as e: print("Error, command %s not found" % e.filename) # TODO timeout # TODO test with missing command if rc == 0: # If the return code on the previous command exited with a 0 error code, # then buzz the buzzer, set the authorized propety on our object to true # and the badge_id property to the value returned by the badge reader. self.authorized = True self.badge_id = badge_id # Read the "auth" section of authboxrc and retieve the duration setting. # If there is no value set, default to 30 seconds. self.door_timer.set( self.config.get_int_seconds('auth', 'duration', '30s')) # Enable the pin defined in our "enable_output" configuration definition # (defined in the __init__ of this class), setting it to an "on" value. self.enable_output.on() else: # If the command did not return a zero error code, then buzz the buzzer, # terminate any sounds which may be playing, determine from the "enable" # value in the "sounds" section of the authboxrc config if sounds should # be enabled. # If sounds are to be enabled, then also within the "sounds" section of # the authboxrc config file, determine the audio file based on the # value of "sad_filename" and supply it to the command defined by the # value of "command". if self.noise: self.noise.kill() if self.config.get('sounds', 'enable') == '1': sound_command = self._get_command_line( 'sounds', 'command', [self.config.get('sounds', 'sad_filename')]) self.noise = subprocess.Popen(sound_command, stdin=DEVNULL, stdout=DEVNULL, stderr=DEVNULL) def abort(self, source): """Perform operations on authorization timeout. Args: source: the device a user attempted to authorize for use, but was denied """ print "Abort", source self.authorized = False self.enable_output.off() self.buzzer.off() if self.noise: self.noise.kill() self.noise = None