Example #1
0
    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
Example #2
0
    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
Example #3
0
    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)
Example #4
0
    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.")
Example #5
0
    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.")