def score_job(self, job, job_data): api_debug( 'SCORING', 'Begin Host scoring on Host "%s"' % self.get_canonical_name()) with atomic(): if self.ping_min == 0: ping_ratio = int(self.team.game.get_option('host_ping_ratio')) else: ping_ratio = self.ping_min try: ping_sent = int(job_data['ping_sent']) ping_respond = int(job_data['ping_respond']) try: self.ping_last = math.floor( (float(ping_respond) / float(ping_sent)) * 100) self.online = (self.ping_last >= ping_ratio) except ZeroDivisionError: self.online = False self.ping_last = 0 api_debug( 'SCORING', 'Host "%s" was set "%s" by Job "%d".' % (self.fqdn, ('Online' if self.online else 'Offline'), job.id)) self.save() except ValueError: api_error( 'SCORING', 'Error translating ping responses from Job "%d"!' % job.id) self.online = False self.ping_last = 0 self.save() if 'services' not in job_data and self.online: api_error( 'SCORING', 'Host "%s" was set online by Job "%d" but is missing services!' % (self.fqdn, job.id)) return for service in self.services.all(): if not self.online: service.status = 2 service.save() else: for job_service in job_data['services']: try: if service.port == int(job_service['port']) and \ service.get_protocol_display().lower() == job_service['protocol'].lower(): service.score_job(job, job_service) break except ValueError: pass api_debug( 'SCORING', 'Finished scoring Host "%s" by Job "%d".' % (self.fqdn, job.id)) api_score(self.id, 'HOST-JOB', self.get_canonical_name(), 0)
def api_register_port(request): if request.method == METHOD_GET: port_list = [] for game in Game.objects.filter(status=CONST_GAME_GAME_RUNNING): for port in game.ports.all(): if port not in port_list: port_list.append(port.port) return HttpResponse(content='{"ports": [%s]}' % ','.join([str(i) for i in port_list])) if request.method == METHOD_POST: team, token, data, exception = game_team_from_token( request, 'CLI', 'token', fields=['port']) del token if exception is not None: return exception try: port = int(data['port']) except ValueError: api_error( 'CLI', 'Port submitted by Team "%s" is not an Integer!' % team.get_canonical_name(), request) return HttpResponseBadRequest( content='{"message": "SBE API: Port is not an Integer!"}') del data api_info( 'CLI', 'Team "%s" requested a new Beacon port "%d/tcp"!' % (team.get_canonical_name(), port), request) try: team.game.ports.all().get(port=port) api_debug( 'CLI', 'Port requested by Team "%s" is already open!' % team.get_canonical_name(), request) del team return HttpResponse(status=418) except GamePort.DoesNotExist: game_port = GamePort() game_port.port = port game_port.save() team.game.ports.add(game_port) team.game.save() api_debug( 'CLI', 'Port "%d" requested by Team "%s" was opened!' % (port, team.get_canonical_name()), request) del team del game_port return HttpResponse(status=201) return HttpResponseBadRequest( content='{"message": "SBE API: Not a supported method type!"}')
def score_job(self, job, job_data): if 'status' not in job_data: api_error( 'SCORING', 'Invalid Service "%s" JSON data by Job "%d"!' % (self.get_canonical_name(), job.id)) return with atomic(): service_status = self.status job_status = job_data['status'].lower() for status_value in CONST_GRID_SERVICE_STATUS_CHOICES: if status_value[1].lower() == job_status: service_status = status_value[0] break if service_status == 0 and self.bonus and not self.bonus_started: self.bonus_started = True self.status = service_status self.save() api_debug( 'SCORING', 'Service "%s" was set "%s" by Job "%d".' % (self.get_canonical_name(), self.get_status_display(), job.id)) if 'content' in job_data and self.content is not None: if 'status' in job_data['content']: try: self.content.status = int(job_data['content']['status']) api_debug( 'SCORING', 'Service Content for "%s" was set to "%d" by Job "%d".' % (self.get_canonical_name(), self.content.status, job.id)) except ValueError: self.content.status = 0 api_error( 'SCORING', 'Service Content for "%s" was invalid in Job "%d".' % (self.get_canonical_name(), job.id)) else: self.content.status = 0 api_error( 'SCORING', 'Service Content for "%s" was invalid in Job "%d".' % (self.get_canonical_name(), job.id)) self.content.save() elif self.content is not None: self.content.status = 0 self.content.save() api_error( 'SCORING', 'Service Content for "%s" was ignored by Job "%d".' % (self.get_canonical_name(), job.id)) api_debug( 'SCORING', 'Finished scoring Service "%s" by Job "%d".' % (self.get_canonical_name(), job.id)) api_score(self.id, 'SERVICE-JOB', self.get_canonical_name(), 0)
def score_job(self, monitor, job, job_data): if self.monitor.id != monitor.id: api_error( 'JOB', 'Monitor "%s" returned a Job created by Monitor "%s"!' % (monitor.name, job.monitor.name)) return False, 'Job was submitted by a different monitor!' api_info( 'JOB', 'Processing Job "%d" send by Monitor "%s".' % (job.id, monitor.name)) if self.game.status != CONST_GAME_GAME_RUNNING: api_error( 'JOB', 'Job Game "%s" submitted by Monitor "%s" is not Running!' % (self.game, job.monitor.name)) return False, 'Game is not running!' try: job.host.score_job(job, job_data['host']) except KeyError: api_error( 'JOB', 'Job submitted by Monitor "%s" is not in a correct JSON format!' % self.monitor.name) return False, 'Not in a valid JSON format!' api_debug('JOB', 'Job "%d" processing finished!' % job.id) job.finish = timezone.now() job.save() return True, None
def api_ticket(request): if request.method == METHOD_POST: try: decoded_data = request.body.decode('UTF-8') except UnicodeDecodeError: api_error('TICKET', 'Data submitted is not encoded properly!', request) return HttpResponseBadRequest( content= '{"message": "SBE API: Incorrect encoding, please use UTF-8!"}' ) try: json_data = json.loads(decoded_data) del decoded_data except json.decoder.JSONDecodeError: api_error('TICKET', 'Data submitted is not in correct JSON format!', request) return HttpResponseBadRequest( content= '{"message": "SBE API: Not in a valid JSON format!"]') if 'tickets' not in json_data: api_error('TICKET', 'Data submitted is missing JSON fields!', request) return HttpResponseBadRequest( content= '{"message": "SBE API: Not in a valid JSON format!"}') if not isinstance(json_data['tickets'], list): api_error('TICKET', 'Data submitted is missing JSON fields!', request) return HttpResponseBadRequest( content= '{"message": "SBE API: Not in a valid JSON format!"}') for ticket in json_data['tickets']: ticket, exception = GameTicket.grab_ticket_json( request, ticket) if exception: return HttpResponseBadRequest( '{"message": "SBE API: d%s"}' % exception) del ticket return HttpResponse(status=200, content='{"message": "Accepted"}') return HttpResponseBadRequest( content='{"message": "SBE API: Not a supported method type!"}')
def api_uuid(request, game_id): if request.method == METHOD_GET: try: game = Game.objects.get(id=int(game_id)) except ValueError: api_error('MAPPER', 'Attempted to get non-existent Game "%d"!' % game_id, request) return HttpResponseNotFound() except Game.DoesNotExist: api_error('MAPPER', 'Attempted to get non-existent Game "%d"!' % game_id, request) return HttpResponseNotFound() except Game.MultipleObjectsReturned: api_error('MAPPER', 'Attempted to get non-existent Game "%d"!' % game_id, request) return HttpResponseNotFound() if game.status != CONST_GAME_GAME_RUNNING: api_error( 'MAPPER', 'Attempted to get a non-running Game "%s"!' % game.name, request) return HttpResponseForbidden( content='{"message": "SBE API: Game "%s" is not Running!"}' % game.name) api_info('MAPPER', 'Returned UUID mappings for Game "%s"!' % game.name, request) json_data = { 'teams': [t.get_json_mapper() for t in game.teams.all()] } return HttpResponse(status=200, content=json.dumps(json_data)) return HttpResponseBadRequest( content='{"message": "SBE API: Not a supported method type!"}')
def api_purchase(request, team_id=None): if request.method == METHOD_GET: api_debug('STORE', 'Requesting the exchange rate for Team "%s"' % team_id, request) if team_id is None: api_error('STORE', 'Attempted to use Null Team ID!', request) return HttpResponseNotFound( '{"message": "SBE API: Team could not be found!"}') try: team = GameTeam.objects.get( store=int(team_id), game__status=CONST_GAME_GAME_RUNNING) except ValueError: api_error( 'STORE', 'Attempted to use an invalid Team ID "%s"!' % str(team_id), request) return HttpResponseNotFound( '{"message": "SBE API: Invalid Team ID!"}') except GameTeam.DoesNotExist: api_error( 'STORE', 'Attempted to use an non-existent Team ID "%s"!' % str(team_id), request) return HttpResponseNotFound( '{"message": "SBE API: Team could not be found!"}') except GameTeam.MultipleObjectsReturned: api_error( 'STORE', 'Attempted to use a Team ID which returned multiple Teams!', request) return HttpResponseNotFound( '{"message": "SBE API: Team could not be found!"}') rate = float(team.game.get_option('score_exchange_rate')) / 100.0 api_debug( 'STORE', 'The exchange rate for Team "%s" is "%.2f"!' % (team.get_canonical_name(), rate), request) return HttpResponse(status=200, content='{"rate": %.2f}' % rate) if request.method == METHOD_POST: try: decoded_data = request.body.decode('UTF-8') except UnicodeDecodeError: api_error('STORE', 'Data submitted is not encoded properly!', request) return HttpResponseBadRequest( content= '{"message": "SBE API: Incorrect encoding, please use UTF-8!"}' ) try: json_data = json.loads(decoded_data) del decoded_data except json.decoder.JSONDecodeError: api_error('STORE', 'Data submitted is not in correct JSON format!', request) return HttpResponseBadRequest( content= '{"message": "SBE API: Not in a valid JSON format!"]') if 'team' not in json_data or 'order' not in json_data: api_error('STORE', 'Data submitted is missing JSON fields!', request) return HttpResponseBadRequest( content= '{"message": "SBE API: Not in a valid JSON format!"}') try: team = GameTeam.objects.get( store=int(json_data['team']), game__status=CONST_GAME_GAME_RUNNING) except ValueError: api_error( 'STORE', 'Attempted to use an invalid Team ID "%s"!' % str(team_id), request) return HttpResponseNotFound( '{"message": "SBE API: Invalid Team ID!"}') except GameTeam.DoesNotExist: api_error( 'STORE', 'Attempted to use an non-existent Team ID "%s"!' % str(team_id), request) return HttpResponseNotFound( '{"message": "SBE API: Team could not be found!"}') except GameTeam.MultipleObjectsReturned: api_error( 'STORE', 'Attempted to use a Team ID which returned multiple Teams!', request) return HttpResponseNotFound( '{"message": "SBE API: Team could not be found!"}') api_info( 'STORE', 'Attempting to add Purchase records for Team "%s".' % team.get_canonical_name(), request) if not isinstance(json_data['order'], list): api_error('STORE', 'Data submitted is missing the "oreer" array!', request) return HttpResponseBadRequest( content='{"message": "SBE API: Not in valid JSON format!"}' ) for order in json_data['order']: if 'item' in order and 'price' in order: try: with atomic(): purchase = Purchase() purchase.team = team purchase.amount = int( float(order['price']) * (float( team.game.get_option( 'score_exchange_rate')) / 100.0)) purchase.item = (order['item'] if len(order['item']) < 150 else order['item'][:150]) team.set_uptime(-1 * purchase.amount) purchase.save() api_score(team.id, 'PURCHASE', team.get_canonical_name(), purchase.amount, purchase.item) api_debug( 'STORE', 'Processed order of "%s" "%d" for team "%s"!' % (purchase.item, purchase.amount, team.get_canonical_name()), request) del purchase except ValueError: api_warning( 'STORE', 'Order "%s" has invalid integers for amount!!' % str(order), request) else: api_warning( 'STORE', 'Order "%s" does not have the correct format!' % str(order), request) return HttpResponse(status=200, content='{"message": "processed"}') return HttpResponseBadRequest( content='{"message": "SBE API: Not a supported method type!"}')
def api_transfer(request): if request.method == METHOD_POST: try: decoded_data = request.body.decode('UTF-8') except UnicodeDecodeError: api_error('TRANSFER', 'Data submitted is not encoded properly!', request) return HttpResponseBadRequest( content= '{"message": "SBE API: Incorrect encoding, please use UTF-8!"}' ) try: json_data = json.loads(decoded_data) del decoded_data except json.decoder.JSONDecodeError: api_error('TRANSFER', 'Data submitted is not in correct JSON format!', request) return HttpResponseBadRequest( content= '{"message": "SBE API: Not in a valid JSON format!"]') if 'target' not in json_data or 'dest' not in json_data or 'amount' not in json_data: api_error('TRANSFER', 'Data submitted is missing JSON fields!', request) return HttpResponseBadRequest( content= '{"message": "SBE API: Not in a valid JSON format!"}') if json_data['target'] is None and json_data['dest'] is None: api_error('TRANSFER', 'Cannot transfer from Gold to Gold!', request) return HttpResponseBadRequest( content= '{"message": "SBE API: Cannot transfer from Gold to Gold!"}' ) team_to = None team_from = None try: amount = int(json_data['amount']) except ValueError: api_error('TRANSFER', 'Amount submitted is is invalid!', request) return HttpResponseBadRequest( content='{"message": "SBE API: Invalid amount!"}') if amount <= 0: api_error('TRANSFER', 'Amount submitted is is invalid!', request) return HttpResponseBadRequest( content='{"message": "SBE API: Invalid amount!"}') if json_data['dest'] is not None: try: team_token = Token.objects.get( uuid=uuid.UUID(json_data['dest'])) team_to = GameTeam.objects.get(token=team_token) del team_token except ValueError: api_error('TRANSFER', 'Token given for Destination is invalid!', request) return HttpResponseBadRequest( content= '{"message": "SBE API: Invalid Destination Token!"}') except Token.DoesNotExist: api_error('TRANSFER', 'Token given for Destination is invalid!', request) return HttpResponseBadRequest( content= '{"message": "SBE API: Invalid Destination Token!"}') except GameTeam.DoesNotExist: api_error('TRANSFER', 'Team given for Destination does not exist!', request) return HttpResponseBadRequest( content= '{"message": "SBE API: Destination Team does not exist!"}' ) if json_data['target'] is not None: try: team_token = Token.objects.get( uuid=uuid.UUID(json_data['target'])) team_from = GameTeam.objects.get(token=team_token) del team_token except ValueError: api_error('TRANSFER', 'Token given for Source is invalid!', request) return HttpResponseBadRequest( content='{"message": "SBE API: Invalid Source Token!"}' ) except Token.DoesNotExist: api_error('TRANSFER', 'Token given for Source is invalid!', request) return HttpResponseBadRequest( content='{"message": "SBE API: Invalid Source Token!"}' ) except GameTeam.DoesNotExist: api_error('TRANSFER', 'Team given for Source does not exist!', request) return HttpResponseBadRequest( content= '{"message": "SBE API: Source Team does not exist!"}') if team_to is not None and team_to.game.status != CONST_GAME_GAME_RUNNING: api_error( 'TRANSFER', 'Game "%s" submitted is not Running!' % team_to.gane.name, request) return HttpResponseBadRequest( content='{"message": "SBE API: Team Game ius not running!"}' ) if team_from is not None and team_from.game.status != CONST_GAME_GAME_RUNNING: api_error( 'TRANSFER', 'Game "%s" submitted is not Running!' % team_from.gane.name, request) return HttpResponseBadRequest( content='{"message": "SBE API: Team Game ius not running!"}' ) if team_to is not None and team_from is not None and team_to.game.id != team_from.game.id: api_error('TRANSFER', 'Transfer teams are not in the same Game!', request) return HttpResponseBadRequest( content= '{"message": "SBE API: Teams are not in the same Game!"}') with atomic(): if team_from is not None: team_from.set_uptime(-1 * amount) api_score(team_from.id, 'TRANSFER', team_from.get_canonical_name(), -1 * amount, ('GoldTeam' if team_to is None else team_to.get_canonical_name())) if team_to is not None: team_to.set_uptime(amount) api_score(team_to.id, 'TRANSFER', team_to.get_canonical_name(), amount, ('GoldTeam' if team_from is None else team_from.get_canonical_name())) return HttpResponse(status=200, content='{"message": "transferred"}') return HttpResponseBadRequest( content='{"message": "SBE API: Not a supported method type!"}')
def api_job(request): try: monitor = Monitor.objects.get(access=request.authentication) except Monitor.DoesNotExist: api_error( 'JOB', 'Attempted to request a Job without Monitor permissions!', request) return HttpResponseForbidden( '{"message": "SBE API: Only registered Monitors may request Jobs!"}' ) game_monitors = GameMonitor.objects.filter( monitor=monitor, game__status=CONST_GAME_GAME_RUNNING) if len(game_monitors) == 0: api_error( 'JOB', 'Monitor "%s" attempted to request a Job but is not registered in any Games!' % monitor.name, request) return HttpResponseForbidden( '{"message": "SBE API: Not registered with any running Games!"}' ) if request.method == METHOD_GET: games_max = len(game_monitors) api_debug( 'JOB', 'Monitor "%s" is requesting a Job and has "%d" Games to choose from!' % (monitor.name, games_max), request) for game_round in range(0, games_max): game_monitor = random.choice(game_monitors) api_debug( 'JOB', 'Monitor "%s" has picked game "%s"!' % (monitor.name, game_monitor.game.name), request) job_data = game_monitor.create_job() if job_data: dump_data('job-%s' % game_monitor.monitor.name, job_data) del game_monitor return HttpResponse(status=201, content=job_data) del game_monitor del monitor del games_max del game_monitors return HttpResponse( status=204, content='{"message": "SBE API: No Hosts available! Try later."}' ) elif request.method == METHOD_POST: api_debug('JOB', 'Monitor "%s" is submitting a Job!' % monitor.name, request) try: decoded_data = request.body.decode('UTF-8') except UnicodeDecodeError: api_error( 'JOB', 'Job submitted by Monitor "%s" is not encoded properly!' % monitor.name, request) return HttpResponseBadRequest( '{"message": "SBE API: Incorrect encoding, please use UTF-8!"}' ) try: job_json = json.loads(decoded_data) del decoded_data except json.decoder.JSONDecodeError: api_debug( 'JOB', 'Job submitted by Monitor "%s" is not in a valid JSON format!' % monitor.name, request) return HttpResponseBadRequest( '{"message": "SBE API: Not in a valid JSON format!"}') try: job = Job.objects.get(id=int(job_json['id'])) if job.finish is not None: logger.warning( 'SBE-JOB', 'Monitor "%s" returned a completed Job!' % monitor.name) return HttpResponseBadRequest( '{"message": "SBE API: Job already completed!"}') except KeyError: api_error( 'JOB', 'Job submitted by Monitor "%s" is not in a correct JSON format!' % monitor.name, request) return HttpResponseBadRequest( '{"message": "SBE API: Not in a valid JSON format!"}') except ValueError: api_error( 'JOB', 'Monitor "%s" returned a Job with an invalid ID!' % monitor.name, request) return HttpResponseBadRequest( '{"message": "SBE API: Invalid Job ID!"}') except TypeError: api_error( 'JOB', 'Job submitted by Monitor "%s" is not in correct JSON format!' % monitor.name, request) return HttpResponseBadRequest( '{"message": "SBE API: Not in valid JSON format!"}') except Job.DoesNotExist: api_error( 'JOB', 'Monitor "%s" returned a Job with an non-existent ID "%d" !' % (monitor.name, job_json['id']), request) return HttpResponseBadRequest( '{"message:", "SBE API: Job with ID \'%d\' does not exist!"}' % job_json['id']) dump_data('job-%s' % monitor.name, job_json) status, message = job.monitor.score_job(monitor, job, job_json) del job del monitor del game_monitors if status: return HttpResponse( status=202, content='{"message": "SBE API: Job Accepted"}') return HttpResponseBadRequest( content='{"message": "SBE API: %s"}' % message) return HttpResponseBadRequest( content='{"message": "SBE API: Not a supported method type!"}')
def api_beacon(request): if request.method == METHOD_POST: team, token, data, exception = game_team_from_token( request, 'CLI', 'token', beacon=True, fields=['address']) if exception is not None: return exception address_raw = data['address'] try: address = IPAddress(address_raw) except AddrFormatError: api_error( 'BEACON', 'IP Reported by Team "%s" is invalid!' % team.get_canonical_name(), request) return HttpResponseBadRequest( content='{"message": "SBE API: Invalid IP Address!"}') target_team = None for sel_target_team in team.game.teams.all(): try: target_subnet = IPNetwork(sel_target_team.subnet) except AddrFormatError: api_warning( 'BEACON', 'Team "%s" subnet is invalid, skipping Team!' % team.get_canonical_name(), request) continue if address in target_subnet: api_debug( 'BEACON', 'Beacon from Team "%s" to Team "%s"\'s subnet!' % (team.get_canonical_name(), sel_target_team.get_canonical_name()), request) target_team = sel_target_team del target_subnet break del target_subnet del address try: host = Host.objects.get( ip=address_raw, team__game__status=CONST_GAME_GAME_RUNNING) if host.team.game.id != team.game.id: api_error( 'BEACON', 'Host accessed by Team "%s" is not in the same game as "%s"!' % (team.get_canonical_name(), host.team.get_canonical_name()), request) return HttpResponseForbidden( '{"message": "SBE API: Host is not in the same Game!"}' ) try: beacon = host.beacons.get(beacon__finish__isnull=True, beacon__attacker=team, beacon__token=token) beacon.checkin = timezone.now() beacon.save() api_info( 'BEACON', 'Team "%s" updated the Beacon on Host "%s"!' % (team.get_canonical_name(), host.get_canonical_name()), request) return HttpResponse() except GameCompromiseHost.MultipleObjectsReturned: api_warning( 'BEACON', 'Team "%s" attempted to create multiple Beacons on a Host "%s"!' % (team.get_canonical_name(), host.get_canonical_name()), request) del host del address_raw return HttpResponseForbidden( '{"message": "SBE API: Already a Beacon on that Host!"}' ) except GameCompromiseHost.DoesNotExist: if host.beacons.filter( beacon__finish__isnull=True).count() > 1: api_warning( 'BEACON', 'Team "%s" attempted to create multiple Beacons on a Host "%s"!' % (team.get_canonical_name(), host.get_canonical_name()), request) del host del address_raw return HttpResponseForbidden( '{"message": "SBE API: Already a Beacon on that Host!"}' ) with atomic(): beacon = GameCompromise() beacon_host = GameCompromiseHost() beacon_host.ip = address_raw beacon_host.team = host.team beacon_host.host = host beacon.token = token beacon.attacker = team beacon.save() beacon_host.beacon = beacon beacon_host.save() api_event( team.game, 'A Host on %s\'s network was compromised by "%s" #PvJCTF #CTF #BSidesLV!' % (host.team.name, team.name)) beacon_value = int( team.game.get_option('beacon_value')) team.set_beacons(beacon_value) api_info( 'SCORING-ASYNC', 'Beacon score was applied to Team "%s"!' % team.get_canonical_name(), request) api_score(beacon.id, 'BEACON-ATTACKER', team.get_canonical_name(), beacon_value, beacon_host.get_fqdn()) del beacon_value del beacon del beacon_host del address_raw api_info( 'BEACON', 'Team "%s" added a Beacon to Host "%s"!' % (team.get_canonical_name(), host.get_canonical_name()), request) return HttpResponse(status=201) except Host.DoesNotExist: if target_team is not None: api_info( 'BEACON', 'Host accessed by Team "%s" does not exist! Attempting to create a faux Host!' % team.get_canonical_name(), request) if GameCompromiseHost.objects.filter( ip=address_raw, beacon__finish__isnull=True).count() > 0: api_warning( 'BEACON', 'Team "%s" attempted to create multiple Beacons on a Host "%s"!' % (team.get_canonical_name(), address_raw), request) del address_raw return HttpResponseForbidden( '{"message": "SBE API: Already a Beacon on that Host!"}' ) with atomic(): beacon_host = GameCompromiseHost() beacon_host.ip = address_raw beacon_host.team = target_team beacon = GameCompromise() beacon.token = token beacon.attacker = team beacon.save() beacon_host.beacon = beacon beacon_host.save() api_event( team.game, 'A Host on %s\'s network was compromised by "%s" #PvJCTF #CTF #BSidesLV!' % (target_team.name, team.name)) beacon_value = int( team.game.get_option('beacon_value')) team.set_beacons(beacon_value) api_info( 'SCORING-ASYNC', 'Beacon score was applied to Team "%s"!' % team.get_canonical_name(), request) api_score(beacon.id, 'BEACON-ATTACKER', team.get_canonical_name(), beacon_value, beacon_host.get_fqdn()) del beacon_value del beacon del beacon_host api_info( 'BEACON', 'Team "%s" added a Beacon to Host "%s"!' % (team.get_canonical_name(), address_raw), request) del address_raw return HttpResponse(status=201) del address_raw api_error( 'BEACON', 'Host accessed by Team "%s" does not exist and a hosting team cannot be found!' % team.get_canonical_name(), request) return HttpResponseNotFound( '{"message": "SBE API: Host does not exist!"}') except Host.MultipleObjectsReturned: api_error( 'BEACON', 'Host accessed by Team "%s" returned multiple Hosts, invalid!' % team.get_canonical_name(), request) return HttpResponseNotFound( '{"message": "SBE API: Host does not exist!"}') return HttpResponseBadRequest( content='{"message": "SBE API: Not a supported method type!"}')
def api_flag(request): if request.method == METHOD_POST: team, token, data, exception = game_team_from_token( request, 'Flag', 'token', fields=['flag']) del token if exception is not None: return exception try: flag = Flag.objects.exclude(team=team).get( host__team__game=team.game, flag__exact=data['flag'], enabled=True) except Flag.DoesNotExist: api_error( 'FLAG', 'Flag submitted by Team "%s" was not found!' % team.get_canonical_name(), request) return HttpResponseNotFound( content='{"message": "SBE API: Flag not valid!"}') except Flag.MultipleObjectsReturned: api_error( 'FLAG', 'Flag submitted by Team "%s" returned multiple flags!' % team.get_canonical_name(), request) return HttpResponseNotFound( content='{"message": "SBE API: Flag not valid!"}') if flag.captured is not None: api_error( 'FLAG', 'Flag "%s" submitted by Team "%s" was already captured!' % (flag.get_canonical_name(), team.get_canonical_name()), request) return HttpResponse( status=204, content='{"message": "SBE API: Flag already captured!"}') flag.capture(team) api_info( 'FLAG', 'Flag "%s" was captured by team "%s"!' % (flag.get_canonical_name(), team.get_canonical_name()), request) try: api_debug( 'FLAG', 'Attempting to get another non-captured flag for a hint..', request) flag_next = random.choice( Flag.objects.filter(enabled=True, team=flag.team, captured__isnull=True)) del flag if flag_next is not None: api_debug( 'FLAG', 'Got Flag "%s", sending hint!' % flag_next.get_canonical_name(), request) return HttpResponse(status=200, content='{"message": "%s"}' % flag_next.description) except IndexError: return HttpResponse(status=200) except Flag.DoesNotExist: return HttpResponse(status=200) return HttpResponseBadRequest( content='{"message": "SBE API: Not a supported method type!"}')
def grab_ticket_json(request, json_data): if 'id' not in json_data or 'name' not in json_data or 'details' not in json_data or \ 'type' not in json_data or 'status' not in json_data or 'team' not in json_data: api_error( 'TICKET', 'Attempted to create a Ticket without the proper values!', request) return None, 'Invalid JSON Data!' api_debug('TICKET', 'Attempting to grab a Ticket from JSON data!', request) ticket = None ticket_exists = False try: ticket = GameTicket.objects.get(ticket_id=int(json_data['id'])) ticket_exists = True except ValueError: api_error('TICKET', 'Attempted to use an invalid ticket ID!', request) return None, 'Invalid Ticket ID!' except GameTicket.DoesNotExist: ticket = GameTicket() ticket.ticket_id = int(json_data['id']) api_info('TICKET', 'Created a new Ticket with ID "%d"!' % ticket.ticket_id, request) except GameTicket.MultipleObjectsReturned: api_error( 'TICKET', 'Multiple Tickets were returned with ID "%s", invalid!' % json_data['id'], request) return None, 'Invalid Ticket ID!' if not ticket_exists: try: team_token = Token.objects.get( uuid=uuid.UUID(json_data['team'])) ticket.team = GameTeam.objects.get(token=team_token) del team_token except ValueError: api_error('TICKET', 'Token given for Team is invalid!', request) return None, 'Invalid Team Token!' except Token.DoesNotExist: api_error('TICKET', 'Token given for Team is invalid!', request) return None, 'Invalid Team Token!' except GameTeam.DoesNotExist: api_error('TICKET', 'Team given does not exist!', request) return None, 'Team does not exist!' else: api_info('TICKET', 'Updating a Ticket with ID "%d"!' % ticket.ticket_id, request) ticket.name = json_data['name'] ticket.description = json_data['details'] ticket_type = json_data['type'].lower() for type in CONST_GRID_TICKET_CATEGORIES_CHOICES: if type[1].lower() == ticket_type: ticket.type = type[0] break del ticket_type if json_data['status'].lower() == 'closed': if ticket_exists and not ticket.closed: ticket.close_ticket() elif not ticket_exists: ticket.closed = True else: if ticket_exists and ticket.closed: ticket.reopen_ticket() del json_data del ticket_exists ticket.save() return ticket, None
def grab_ticket_json(request, json_data): if ("id" not in json_data or "name" not in json_data or "details" not in json_data or "type" not in json_data or "status" not in json_data or "team" not in json_data): api_error( "TICKET", "Attempted to create a Ticket without the proper values!", request, ) return None, "Invalid JSON Data!" api_debug("TICKET", "Attempting to grab a Ticket from JSON data!", request) ticket = None ticket_exists = False try: ticket = GameTicket.objects.get(ticket_id=int(json_data["id"])) ticket_exists = True except ValueError: api_error("TICKET", "Attempted to use an invalid ticket ID!", request) return None, "Invalid Ticket ID!" except GameTicket.DoesNotExist: ticket = GameTicket() ticket.ticket_id = int(json_data["id"]) api_info( "TICKET", 'Created a new Ticket with ID "%d"!' % ticket.ticket_id, request, ) except GameTicket.MultipleObjectsReturned: api_error( "TICKET", 'Multiple Tickets were returned with ID "%s", invalid!' % json_data["id"], request, ) return None, "Invalid Ticket ID!" if not ticket_exists: try: team_token = Token.objects.get( uuid=uuid.UUID(json_data["team"])) ticket.team = GameTeam.objects.get(token=team_token) del team_token except ValueError: api_error("TICKET", "Token given for Team is invalid!", request) return None, "Invalid Team Token!" except Token.DoesNotExist: api_error("TICKET", "Token given for Team is invalid!", request) return None, "Invalid Team Token!" except GameTeam.DoesNotExist: api_error("TICKET", "Team given does not exist!", request) return None, "Team does not exist!" else: api_info("TICKET", 'Updating a Ticket with ID "%d"!' % ticket.ticket_id, request) ticket.name = json_data["name"] ticket.description = json_data["details"] ticket_type = json_data["type"].lower() for type in CONST_GRID_TICKET_CATEGORIES_CHOICES: if type[1].lower() == ticket_type: ticket.type = type[0] break del ticket_type if json_data["status"].lower() == "closed": if ticket_exists and not ticket.closed: ticket.close_ticket() elif not ticket_exists: ticket.closed = True else: if ticket_exists and ticket.closed: ticket.reopen_ticket() del json_data del ticket_exists ticket.save() return ticket, None