def post(self): """Post handler for emergency controls.""" logging.debug('Emergency handler post method called.') big_red_button = big_red.BigRedButton() # The handler expects only one emergency value each time it's called. # The individual switch being thrown will either be 'true' or 'false'. if self.request.get('bigRedButton') == 'false': big_red_button.turn_everything_off() elif self.request.get('bigRedButton') == 'true': big_red_button.turn_on_big_red_button() elif self.request.get('bigRedButtonStop1') == 'true': big_red_button.turn_on_stop1() elif self.request.get('bigRedButtonStop2') == 'true': big_red_button.turn_on_stop2() elif self.request.get('bigRedButtonGo1') == 'true': big_red_button.turn_on_go1() elif self.request.get('bigRedButtonGo2') == 'true': big_red_button.turn_on_go2() else: self.abort(httplib.BAD_REQUEST, explanation='Improper switch or value set.') self.respond_json(big_red_button.get_button_status())
def get(self): # pylint: disable=g-bad-name """Get handler for emergency controls.""" logging.debug('Emergency handler get method called.') big_red_button = big_red.BigRedButton() self.respond_json(big_red_button.get_button_status())
def post(self, uuid): futures = [] # Create an User for the reported user on any preflight, # if one doesn't already exist. primary_user = self.parsed_json.get(_PREFLIGHT.PRIMARY_USER) email_addr = user_utils.UsernameToEmail(primary_user) user = user_models.User.GetOrInsert(email_addr=email_addr) # Ensures the returned username is consistent with the User entity. primary_user = user.nickname first_seen = not self.host users_change = not first_seen and primary_user != self.host.primary_user # Create a SantaHost on the first preflight. if first_seen: logging.info('Host %s is syncing for the first time', uuid) self.host = host_models.SantaHost(key=self.host_key) self.host.client_mode = settings.DEFAULT_CLIENT_MODE[ constants.CLIENT.SANTA] futures.append(_CopyLocalRules(user.key, uuid)) # Update the SantaHost on every sync. self.host.serial_num = self.parsed_json.get(_PREFLIGHT.SERIAL_NUM) self.host.hostname = self.parsed_json.get(_PREFLIGHT.HOSTNAME) self.host.primary_user = primary_user self.host.santa_version = self.parsed_json.get( _PREFLIGHT.SANTA_VERSION) self.host.os_version = self.parsed_json.get(_PREFLIGHT.OS_VERSION) self.host.os_build = self.parsed_json.get(_PREFLIGHT.OS_BUILD) self.host.last_preflight_dt = datetime.datetime.utcnow() self.host.last_preflight_ip = self.request.remote_addr reported_mode = self.parsed_json.get(_PREFLIGHT.CLIENT_MODE) if reported_mode != self.host.client_mode: message = 'Client mode mismatch (Expected: %s, Actual: %s)' % ( self.host.client_mode, reported_mode) logging.warning(message) # If the client_mode doesn't correspond to a known value, report it as # UNKNOWN. if reported_mode not in constants.HOST_MODE.SET_ALL: reported_mode = constants.HOST_MODE.UNKNOWN tables.HOST.InsertRow(device_id=uuid, timestamp=datetime.datetime.utcnow(), action=constants.HOST_ACTION.COMMENT, hostname=self.host.hostname, platform=constants.PLATFORM.MACOS, users=[self.host.primary_user], mode=reported_mode, comment=message) if self.parsed_json.get(_PREFLIGHT.REQUEST_CLEAN_SYNC): logging.info('Client requested clean sync') self.host.rule_sync_dt = None # Save the SantaHost entity. futures.append(self.host.put_async()) # If the big red button is pressed, override the self.host.client_mode # set in datastore with either MONITOR or LOCKDOWN for this response only. actual_client_mode = self.host.client_mode big_red_button = big_red.BigRedButton() if big_red_button.stop_stop_stop: actual_client_mode = constants.CLIENT_MODE.MONITOR elif big_red_button.go_go_go: actual_client_mode = constants.CLIENT_MODE.LOCKDOWN # Prepare the response. response = { _PREFLIGHT.BATCH_SIZE: (settings.SANTA_EVENT_BATCH_SIZE), _PREFLIGHT.CLIENT_MODE: actual_client_mode, _PREFLIGHT.WHITELIST_REGEX: (self.host.directory_whitelist_regex if self.host.directory_whitelist_regex is not None else settings.SANTA_DIRECTORY_WHITELIST_REGEX), _PREFLIGHT.BLACKLIST_REGEX: (self.host.directory_blacklist_regex if self.host.directory_blacklist_regex is not None else settings.SANTA_DIRECTORY_BLACKLIST_REGEX), _PREFLIGHT.CLEAN_SYNC: not self.host.rule_sync_dt, _PREFLIGHT.BUNDLES_ENABLED: (settings.SANTA_BUNDLES_ENABLED), _PREFLIGHT.TRANSITIVE_WHITELISTING_ENABLED: (self.host.transitive_whitelisting_enabled), } # Verify all futures resolved successfully. for future in futures: future.check_success() # If this is the first preflight, create a FIRST_SEEN HostRow. This has to # occur after the new SantaHost entity is put(), since SantaHost.recorded_dt # is an auto_now_add. if first_seen: new_host = ndb.Key('Host', uuid).get() tables.HOST.InsertRow(device_id=uuid, timestamp=new_host.recorded_dt, action=constants.HOST_ACTION.FIRST_SEEN, hostname=new_host.hostname, platform=constants.PLATFORM.MACOS, users=[new_host.primary_user], mode=new_host.client_mode) # If there was a user change, create a USERS_CHANGE HostRow. if users_change: tables.HOST.InsertRow(device_id=uuid, timestamp=self.host.recorded_dt, action=constants.HOST_ACTION.USERS_CHANGE, hostname=self.host.hostname, platform=constants.PLATFORM.MACOS, users=[self.host.primary_user], mode=self.host.client_mode) self.respond_json(response)
def setUp(self): super(BigRedButtonTests, self).setUp() self.big_red_button = big_red.BigRedButton() self.SetSwitches(False, self.big_red_button.ALL_SWITCHES)
def post(self, uuid): futures = [] # Create an User for the primary_user on any preflight if one doesn't # already exist. primary_user = self.parsed_json.get(santa_const.PREFLIGHT.PRIMARY_USER) user = base_db.User.GetOrInsert( user_map.UsernameToEmail(primary_user)) # Ensures the returned username is consistent with the User entity. primary_user = user.nickname # Create a SantaHost on the first preflight. first_preflight = not self.host if first_preflight: self.host = santa_db.SantaHost(key=self.host_key) self.host.client_mode = settings.SANTA_DEFAULT_CLIENT_MODE futures.append(self._CreateNewLocalRules(uuid, user.key)) # Update host entity on every sync. self.host.serial_num = self.parsed_json.get( santa_const.PREFLIGHT.SERIAL_NUM) self.host.hostname = self.parsed_json.get( santa_const.PREFLIGHT.HOSTNAME) self.host.primary_user = primary_user self.host.santa_version = self.parsed_json.get( santa_const.PREFLIGHT.SANTA_VERSION) self.host.os_version = self.parsed_json.get( santa_const.PREFLIGHT.OS_VERSION) self.host.os_build = self.parsed_json.get( santa_const.PREFLIGHT.OS_BUILD) self.host.last_preflight_dt = datetime.datetime.utcnow() self.host.last_preflight_ip = self.request.remote_addr reported_mode = self.parsed_json.get(santa_const.PREFLIGHT.CLIENT_MODE) if reported_mode != self.host.client_mode: msg = 'Client mode mismatch. Expected: %s. Actual: %s' % ( self.host.client_mode, reported_mode) logging.info(msg) futures.append(base_db.AuditLog.CreateAsync(self.host, msg)) if self.parsed_json.get(santa_const.PREFLIGHT.REQUEST_CLEAN_SYNC): logging.info('Client requested clean sync') self.host.rule_sync_dt = None # Save host entity. futures.append(self.host.put_async()) # If the big red button is pressed, override the self.host.client_mode # set in datastore with either MONITOR or LOCKDOWN for this response only. actual_client_mode = self.host.client_mode big_red_button = big_red.BigRedButton() if big_red_button.stop_stop_stop: actual_client_mode = common_const.SANTA_CLIENT_MODE.MONITOR elif big_red_button.go_go_go: actual_client_mode = common_const.SANTA_CLIENT_MODE.LOCKDOWN # Prepare response. response = { santa_const.PREFLIGHT.BATCH_SIZE: ( settings.SANTA_EVENT_BATCH_SIZE), santa_const.PREFLIGHT.CLIENT_MODE: actual_client_mode, santa_const.PREFLIGHT.WHITELIST_REGEX: ( self.host.directory_whitelist_regex), santa_const.PREFLIGHT.BLACKLIST_REGEX: ( self.host.directory_blacklist_regex), santa_const.PREFLIGHT.CLEAN_SYNC: not self.host.rule_sync_dt, santa_const.PREFLIGHT.BUNDLES_ENABLED: ( settings.SANTA_BUNDLES_ENABLED), } if self.host.should_upload_logs: response[santa_const.PREFLIGHT.UPLOAD_LOGS_URL] = ( blobstore.create_upload_url('/api/santa/logupload/%s' % uuid)) # Verify all futures resolved successfully. for future in futures: future.check_success() # If this is the first preflight, create a FIRST_SEEN HostRow. This has to # occur after the new SantaHost entity is put(), since SantaHost.recorded_dt # is an auto_now_add. if first_preflight: new_host = ndb.Key('Host', uuid).get() bigquery.HostRow.DeferCreate( device_id=uuid, timestamp=new_host.recorded_dt, action=common_const.HOST_ACTION.FIRST_SEEN, hostname=new_host.hostname, platform=common_const.PLATFORM.MACOS, users=santa_db.SantaHost.GetAssociatedUsers(uuid), mode=new_host.client_mode) self.respond_json(response)