def scores_grant_flag(self, client, teamid, flagid, value): """ Gives the given flag to the team """ db_store = client['db_store'] # Check that it wasn't already submitted if db_store.find(DBScore, flagid=flagid, teamid=teamid).count() > 0: raise AskgodException("Team already has flag: %s" % flagid) score = DBScore() score.teamid = teamid score.flagid = flagid score.submit_time = datetime.datetime.now() if value is not None: score.value = value else: flags = db_store.find(DBFlag, id=flagid) if flags.count() != 1: raise AskgodException("Couldn't find flagid=%s" % flagid) score.value = flags[0].value db_store.add(score) db_commit(db_store) logging.info("[team %02d] Scores %s points with flagid=%s (admin)" % (score.teamid, score.value, score.flagid)) client['team'] = teamid process_triggers(client) return True
def scores_grant_writeup(self, client, scoreid, value): """ Gives the writeup points to the team """ db_store = client['db_store'] scores = db_store.find(DBScore, id=scoreid) if scores.count() != 1: raise AskgodException("Couldn't find scoreid=%s" % scoreid) score = scores[0] score.writeup_time = datetime.datetime.now() if value is not None: score.writeup_value = value else: score.writeup_value = score.flag.writeup_value db_commit(db_store) logging.info("[team %02d] Scores %s points with a " "writeup for flagid=%s (admin)" % (score.teamid, score.writeup_value, score.flagid)) return True
def teams_setdetails(self, client, fields): """ Set the details for the caller's team """ if not config_get_bool("server", "teams_setdetails", False): raise AskgodException("Setting team details isn't allowed.") db_store = client['db_store'] convert_properties(fields) validate_properties(DBTeam, fields) results = db_store.find(DBTeam, id=client['team']) if results.count() != 1: raise AskgodException("Can't find a match for id=%s" % client['team']) dbentry = results[0] if set(fields.keys()) - set(['name', 'country', 'website']): raise AskgodException("Invalid field provided.") if "country" in fields: if len(fields['country']) != 2 or not fields['country'].isalpha(): raise AskgodException("Invalid country ISO code.") fields['country'] = fields['country'].upper() for key, value in fields.items(): if not value: continue if getattr(dbentry, key): raise AskgodException("Field is already set: %s" % key) setattr(dbentry, key, value) return db_commit(db_store)
def scores_submit_special(self, client, code, flag): """ Submits/validates a special flag (external validator) """ if config_get_bool("server", "scores_read_only", False): return -6 db_store = client['db_store'] if not code or (not isinstance(code, str) and not isinstance(code, unicode)): if not code: logging.debug("[team %02d] No code provided" % client['team']) raise AskgodException("No code provided.") else: logging.debug("[team %02d] Invalid code type: %s (%s)" % (client['team'], code, type(code))) raise AskgodException("Invalid type for code.") if isinstance(code, str): code = code.decode('utf-8') if not flag or (not isinstance(flag, str) and not isinstance(flag, unicode)): if not flag: logging.debug("[team %02d] No flag provided" % client['team']) raise AskgodException("No flag provided.") else: logging.debug("[team %02d] Invalid flag type: %s (%s)" % (client['team'], flag, type(flag))) raise AskgodException("Invalid type for flag.") if isinstance(code, str): flag = flag.decode('utf-8') logging.info("[team %02d] Submits special flag for code: %s => %s" % (client['team'], code, flag)) # NOTE: Intentional, "DBFlag.flag == None" != "DBFlag.flag is not None" results = db_store.find(DBFlag, And(DBFlag.code == code, DBFlag.flag == None, DBFlag.validator != None)) if results.count() == 0: logging.debug("[team %02d] Code '%s' doesn't exist." % (client['team'], code)) notify_flag(client['team'], "", 0, "") raise AskgodException("Invalid code.") for entry in results: # Deal with per-team flags if entry.teamid and entry.teamid != client['team']: continue # Deal with counter-limited flags if entry.counter: count = db_store.find(DBScore, flagid=entry.id).count() if count >= entry.counter: logging.debug("[team %02d] Flag '%s' has been exhausted." % (client['team'], code)) raise AskgodException("Too late, the flag has " "been exhausted.") # Check that it wasn't already submitted if db_store.find(DBScore, flagid=entry.id, teamid=client['team']).count() > 0: logging.debug("[team %02d] Flag '%s' was already submitted." % (client['team'], code)) raise AskgodException("The flag has already been submitted.") # Call validator if subprocess.call(["validator/%s" % entry.validator, str(client['team']), str(code), str(flag)]) != 0: continue # Add to score score = DBScore() score.teamid = client['team'] score.flagid = entry.id score.value = entry.value score.submit_time = datetime.datetime.now() db_store.add(score) db_commit(db_store) logging.info("[team %02d] Scores %s points with flagid=%s" % (client['team'], entry.value, entry.id)) notify_flag(client['team'], entry.code, entry.value, entry.tags) retval = [] # Generate response response = {} response['value'] = score.value if entry.return_string: response['return_string'] = entry.return_string if entry.writeup_value: response['writeupid'] = "WID%s" % score.id retval.append(response) # Process triggers retval += process_triggers(client) return retval logging.debug("[team %02d] Flag '%s' exists but won't validate." % (client['team'], flag)) raise AskgodException("Unknown error with your flag, " "please report this.")
def scores_submit(self, client, flag): """ Submits/validates a flag """ if config_get_bool("server", "scores_read_only", False): raise AskgodException("Server is read-only.") db_store = client['db_store'] if not flag or (not isinstance(flag, str) and not isinstance(flag, unicode)): if not flag: logging.debug("[team %02d] No flag provided" % client['team']) raise AskgodException("No flag provided.") else: logging.debug("[team %02d] Invalid flag type: %s (%s)" % (client['team'], flag, type(flag))) raise AskgodException("Invalid type for flag.") if isinstance(flag, str): flag = flag.decode('utf-8') logging.info("[team %02d] Submits flag: %s" % (client['team'], flag)) results = db_store.find(DBFlag, DBFlag.flag.lower() == flag.lower()) if results.count() == 0: logging.debug("[team %02d] Flag '%s' doesn't exist." % (client['team'], flag)) notify_flag(client['team'], "", 0, "") raise AskgodException("Flag isn't valid.") for entry in results: # Deal with per-team flags if (entry.teamid is not None and entry.teamid != client['team']): continue # Deal with counter-limited flags if entry.counter: count = db_store.find(DBScore, flagid=entry.id).count() if count >= entry.counter: logging.debug("[team %02d] Flag '%s' has been exhausted." % (client['team'], flag)) raise AskgodException("Too late, the flag has " "been exhausted.") # Check that it wasn't already submitted if db_store.find(DBScore, flagid=entry.id, teamid=client['team']).count() > 0: logging.debug("[team %02d] Flag '%s' was already submitted." % (client['team'], flag)) raise AskgodException("The flag has already been submitted.") # Add to score score = DBScore() score.teamid = client['team'] score.flagid = entry.id score.value = entry.value score.submit_time = datetime.datetime.now() db_store.add(score) db_commit(db_store) logging.info("[team %02d] Scores %s points with flagid=%s" % (client['team'], entry.value, entry.id)) notify_flag(client['team'], entry.code, entry.value, entry.tags) retval = [] # Generate response response = {} response['value'] = score.value if entry.return_string: response['return_string'] = entry.return_string if entry.writeup_value: response['writeup_string'] = "WID%s" % score.id retval.append(response) # Process triggers retval += process_triggers(client) return retval logging.debug("[team %02d] Flag '%s' exists but can't be used." % (client['team'], flag)) raise AskgodException("Unknown error with your flag, " "please report this.")