Пример #1
0
 def get(self, *args, **kwargs):
     """ Validates Email and renders login page """
     if len(options.mail_host) > 0:
         error = None
         info = None
         try:
             user_uuid = decode(
                 urlsafe_b64decode(self.get_argument("u", "")))
             token = sha256(urlsafe_b64decode(self.get_argument(
                 "t", ""))).hexdigest()
         except:
             user_uuid = urlsafe_b64decode(
                 encode(self.get_argument("u", "")))
             token = sha256(
                 urlsafe_b64decode(encode(self.get_argument(
                     "t", "")))).hexdigest()
         user = User.by_uuid(user_uuid)
         if user:
             if user.is_email_valid() is True:
                 pass
             elif user.validate_email(token) is True:
                 info = [
                     "Successfully validated email for %s" % user.handle
                 ]
                 user.locked = False
                 self.dbsession.add(user)
                 self.dbsession.commit()
                 self.event_manager.user_joined_team(user)
             else:
                 error = ["Faield to validate email for %s" % user.handle]
         elif len(user_uuid) > 0 and not user:
             error = ["Invalid user for email validation"]
         self.render("public/login.html", info=info, errors=error)
     else:
         self.redirect("public/404")
Пример #2
0
 def write_xml(self, xml_doc):
     """ Write XML document to page """
     self.set_header("Content-Type", "text/xml")
     self.set_header(
         "Content-disposition",
         "attachment; filename=%s.xml"
         % (self.config.game_name.replace("\n", "").replace("\r", ""),),
     )
     self.set_header("Content-Length", len(encode(xml_doc, "utf-8")))
     self.write(encode(xml_doc, "utf-8"))
     self.finish()
Пример #3
0
    def setUp(self):
        self.box, self.corp = create_box()
        self.static_flag = Flag.create_flag(
            _type=FLAG_STATIC,
            box=self.box,
            name="Static Flag",
            raw_token="statictoken",
            description="A static test token",
            value=100,
        )
        self.regex_flag = Flag.create_flag(
            _type=FLAG_REGEX,
            box=self.box,
            name="Regex Flag",
            raw_token="(f|F)oobar",
            description="A regex test token",
            value=200,
        )
        self.file_flag = Flag.create_flag(
            _type=FLAG_FILE,
            box=self.box,
            name="File Flag",
            raw_token=encode("fdata"),
            description="A file test token",
            value=300,
        )
        self.choice_flag = Flag.create_flag(
            _type=FLAG_CHOICE,
            box=self.box,
            name="Choice Flag",
            raw_token=encode("fdata"),
            description="A choice test token",
            value=400,
        )
        self.datetime_flag = Flag.create_flag(
            _type=FLAG_DATETIME,
            box=self.box,
            name="Datetime Flag",
            raw_token="2018-06-22 18:00:00",
            description="A datetime test token",
            value=500,
        )

        dbsession.add(self.static_flag)
        dbsession.add(self.regex_flag)
        dbsession.add(self.file_flag)
        dbsession.add(self.choice_flag)
        dbsession.add(self.datetime_flag)
        dbsession.commit()
Пример #4
0
 def export_game_config(self, root):
     """
     Exports the game configuration options to an XML doc.
     """
     game_elem = ET.SubElement(root, "configuration")
     game_list = options.group_dict("game")
     images = ["ctf_logo", "story_character", "scoreboard_right_image"]
     for key in game_list:
         value = game_list[key]
         if key in images and len(value) > 0:
             if os.path.isfile(value):
                 path = value
             elif os.path.isfile(os.path.join("files", value)):
                 path = os.path.join("files", value)
             elif value[0] == "/" and os.path.isfile(value[1:]):
                 path = value[1:]
             else:
                 continue
             with open(path, mode="rb") as logo:
                 data = logo.read()
                 ET.SubElement(game_elem, key).text = encode(data, "base64")
         elif isinstance(value, list):
             child = ET.Element(key)
             game_elem.append(child)
             for item in value:
                 ET.SubElement(child, "line").text = str(item)
         elif len(str(value)) > 0:
             ET.SubElement(game_elem, key).text = str(value)
Пример #5
0
 def post(self, *args, **kwargs):
     """ Sends the password reset to email """
     user = User.by_email(self.get_argument("email", ""))
     if user is not None and len(options.mail_host) > 0 and len(user.email) > 0:
         reset_token = encode(urandom(16), "hex")
         passtoken = PasswordToken()
         passtoken.user_id = user.id
         passtoken.value = sha256(reset_token).hexdigest()
         self.dbsession.add(passtoken)
         self.dbsession.commit()
         receivers = [user.email]
         message = self.create_reset_message(user, reset_token)
         smtpObj = smtplib.SMTP(options.mail_host, port=options.mail_port)
         smtpObj.set_debuglevel(False)
         try:
             smtpObj.starttls()
             try:
                 smtpObj.login(options.mail_username, options.mail_password)
             except smtplib.SMTPNotSupportedError as e:
                 logging.warn("SMTP Auth issue (%s). Attempting to send anyway." % e)
             smtpObj.sendmail(options.mail_sender, receivers, message)
         finally:
             smtpObj.quit()
         logging.info("Password Reset sent for %s" % user.email)
     elif not len(options.mail_host) > 0:
         logging.info("Password Reset request failed: No Mail Host in Settings.")
     elif user is None or not len(user.email) > 0:
         logging.info("Password Reset request failed: Email does not exist.")
     self.render(
         "public/forgot.html",
         errors=None,
         info=["If the email exists, a password reset has been sent."],
     )
Пример #6
0
    def post(self, *args, **kwargs):
        """ Sends the password reset to email """
        user = User.by_email(self.get_argument("email", ""))
        if user is not None and len(options.mail_host) > 0 and len(
                user.email) > 0:
            reset_token = encode(urandom(16), "hex")
            passtoken = PasswordToken()
            passtoken.user_id = user.id
            passtoken.value = sha256(reset_token).hexdigest()
            self.dbsession.add(passtoken)
            self.dbsession.commit()
            receivers = [user.email]
            message = self.create_message(user, reset_token)
            smtpObj = smtplib.SMTP(options.mail_host, port=options.mail_port)
            smtpObj.set_debuglevel(False)
            try:
                smtpObj.starttls()
                smtpObj.login(options.mail_username, options.mail_password)
                smtpObj.sendmail(options.mail_sender, receivers, message)
            finally:
                smtpObj.quit()

        self.render(
            "public/forgot.html",
            errors=None,
            info=["If the email exists, a password reset has been sent."],
        )
Пример #7
0
 def get(self, *args, **kargs):
     """ Renders AJAX snippit based on URI """
     uri = {"firstlogin": self.firstlogin}
     user = self.get_current_user()
     if user and len(args) and args[0] in uri:
         dialog = uri[args[0]]()
         if isinstance(options.story_signature, list):
             dialog.extend(options.story_signature)
         for index, line in enumerate(dialog):
             try:
                 dialog[index] = line.replace("$user",
                                              str(user.handle)).replace(
                                                  "$reward",
                                                  str(options.bot_reward))
             except:
                 dialog[index] = line.replace("$user", encode(
                     user.handle)).replace("$reward",
                                           ("%d" % options.bot_reward))
         dialog.append(" ")
         try:
             self.write(json.dumps(dialog))
         except:
             self.write(json.dumps(dialog, encoding="latin1"))
     else:
         self.render("public/404.html")
Пример #8
0
 def initialize(self):
     self.xid = decode(encode(os.urandom(16), "hex"))
     if not self.config.use_bots:
         self.close()
     else:
         self.uuid = str(uuid4())
         self.opcodes = {"interrogation_response": self.interrogation_response}
Пример #9
0
 def data(self, value):
     if self.uuid is None:
         self.uuid = str(uuid4())
     self.byte_size = len(value)
     self.checksum = sha1(value).hexdigest()
     with open(options.source_code_market_dir + "/" + self.uuid, "wb") as fp:
         fp.write(str(encode(value, "base64")).encode())
Пример #10
0
 def data(self, value):
     if MAX_FILE_SIZE <= len(value):
         raise ValidationError("File is too large")
     if self.uuid is None:
         self.uuid = str(uuid4())
     self.byte_size = len(value)
     with open(options.share_dir + "/" + self.uuid, "wb") as fp:
         fp.write(encode(value, "base64"))
Пример #11
0
 def to_xml(self, parent):
     attachment_elem = ET.SubElement(parent, "flag_attachment")
     ET.SubElement(attachment_elem, "file_name").text = self.file_name
     with open(options.flag_attachment_dir + "/" + self.uuid,
               mode="rb") as fp:
         data = fp.read()
         ET.SubElement(attachment_elem,
                       "data").text = encode(data, "base64")
Пример #12
0
 def get(self, *args, **kwargs):
     """ Renders the Token Reset page """
     if len(options.mail_host) > 0:
         try:
             user_uuid = decode(urlsafe_b64decode(self.get_argument("u", "")))
             token = sha256(
                 urlsafe_b64decode(self.get_argument("p", ""))
             ).hexdigest()
         except:
             user_uuid = urlsafe_b64decode(encode(self.get_argument("u", "")))
             token = sha256(
                 urlsafe_b64decode(encode(self.get_argument("p", "")))
             ).hexdigest()
         self.render(
             "public/reset.html", errors=None, info=None, token=token, uuid=user_uuid
         )
     else:
         self.redirect("public/404")
Пример #13
0
 def serialize(self):
     """ We use JSON instead of Pickles """
     dump = {
         "session_id": str(self.session_id),
         "data": self.data,
         "expires": str(self.expires),
         "ip_address": self.ip_address,
     }
     return encode(json.dumps(dump), "base64").strip()
Пример #14
0
 def create_reset_message(self, user, token):
     account = encode(user.uuid)
     try:
         account = decode(urlsafe_b64encode(account))
         token = decode(urlsafe_b64encode(token))
     except:
         account = urlsafe_b64encode(account)
         token = urlsafe_b64encode(token)
     if options.ssl:
         origin = options.origin.replace("ws://", "https://").replace(
             "wss://", "https://"
         )
     else:
         origin = options.origin.replace("ws://", "http://")
     reset_url = "%s/reset/token?u=%s&p=%s" % (origin, account, token)
     remote_ip = (
         self.request.headers.get("X-Real-IP")
         or self.request.headers.get("X-Forwarded-For")
         or self.request.remote_ip
     )
     header = []
     header.append("Subject: %s Password Reset" % options.game_name)
     header.append("From: %s <%s>" % (options.game_name, options.mail_sender))
     header.append("To: %s <%s>" % (user.name, user.email))
     header.append("MIME-Version: 1.0")
     header.append('Content-Type: text/html; charset="UTF-8"')
     header.append("Content-Transfer-Encoding: BASE64")
     header.append("")
     f = open("templates/public/reset_email.html", "r")
     template = (
         f.read()
         .replace("\n", "")
         .replace("[Product Name]", options.game_name)
         .replace("{{name}}", user.name)
         .replace("{{action_url}}", reset_url)
         .replace("{{remote_ip}}", remote_ip)
         .replace("https://example.com", origin)
     )
     f.close()
     try:
         email_msg = "\n".join(header) + b64encode(template)
     except:
         email_msg = "\n".join(header) + decode(b64encode(encode(template)))
     return email_msg
Пример #15
0
 def initialize(self):
     try:
         hex_random = os.urandom(16).hex()
     except AttributeError:
         hex_random = encode(os.urandom(16), "hex")
     self.xid = hex_random
     if not self.config.use_bots:
         self.close()
     else:
         self.uuid = str(uuid4())
         self.opcodes = {
             "interrogation_response": self.interrogation_response
         }
Пример #16
0
 def description(self):
     if self._description is None:
         self._description = ""
     ls = []
     if 0 < len(self._description):
         text = self._description.replace("\r\n", "\n").strip()
         ls.append("%s" % text)
     else:
         ls.append("No information on file.")
     if self.difficulty != "Unknown":
         ls.append("Reported Difficulty: %s" % self.difficulty)
     if not encode(ls[-1], "utf-8").endswith(b"\n"):
         ls[-1] = ls[-1] + "\n"
     return str("\n\n".join(ls))
Пример #17
0
 def _hash_bank_password(cls, algorithm_name, password):
     """
     Hashes the password using Md5/Sha1/Sha256/Sha512
     only used for the admin accounts.  We only allow
     whitespace/non-ascii.
     """
     if algorithm_name is None:
         algorithm_name = DEFAULT_HASH_ALGORITHM
     if algorithm_name in cls.algorithms:
         algo = cls.algorithms[algorithm_name][0]()
         algo.update(encode(password))
         return algo.hexdigest()
     else:
         raise ValueError("Algorithm %s not supported." % algorithm_name)
Пример #18
0
    def create_frame(data, opcode):
        """
        create frame to send text, binary and other data.

        data: data to send. This is string value(byte array).
            if opcode is OPCODE_TEXT and this value is unicode,
            data value is converted into unicode string, automatically.

        opcode: operation code. please see OPCODE_XXX.
        """
        if sys.version_info.major == 2:
            instance = isinstance(data, unicode)
        else:
            instance = isinstance(data, str)
        if opcode == ABNF.OPCODE_TEXT and instance:
            data = encode(data, "utf-8")
        # mask must be set if send data from client
        return ABNF(1, 0, 0, 0, opcode, 1, data)
Пример #19
0
 def to_xml(self, parent):
     """
     Admins cannot be exported as XML, not that they would be
     exported because they're not on a team, but check anyways
     """
     if not self.is_admin():
         user_elem = ET.SubElement(parent, "user")
         ET.SubElement(user_elem, "handle").text = self.handle
         ET.SubElement(user_elem, "name").text = self.name
         ET.SubElement(user_elem, "email").text = self.email
         ET.SubElement(user_elem, "password").text = self._password
         bpass_elem = ET.SubElement(user_elem, "bankpassword")
         bpass_elem.text = self._bank_password
         bpass_elem.set("algorithm", self.algorithm)
         with open(options.avatar_dir + self.avatar) as fp:
             data = fp.read()
             ET.SubElement(user_elem,
                           "avatar").text = encode(data, "base64")
Пример #20
0
def create_boxes(parent, corporation):
    """ Create boxes for a corporation """
    if corporation is None:
        return
    logging.info("Found %s boxes" % parent.get("count"))
    for index, box_elem in enumerate(parent):
        try:
            name = get_child_text(box_elem, "name")
            game_level = GameLevel.by_number(
                get_child_text(box_elem, "gamelevel", "0"))
            if game_level is None:
                logging.warning(
                    "GameLevel does not exist for box %s, skipping" % name)
            elif Box.by_name(name) is None:
                box = Box(corporation_id=corporation.id)
                box.name = name
                box.game_level_id = game_level.id
                box.difficulty = get_child_text(box_elem, "difficulty")
                box.flag_submission_type = FlagsSubmissionType[get_child_text(
                    box_elem, "flag_submission_type", "CLASSIC")]

                box.description = get_child_text(box_elem, "description")
                box.capture_message = get_child_text(box_elem,
                                                     "capture_message")
                box.operating_system = get_child_text(box_elem,
                                                      "operatingsystem")
                box.value = get_child_text(box_elem, "value", "0")
                if get_child_text(box_elem, "avatar", "none") != "none":
                    box.avatar = bytearray(
                        b64decode(get_child_text(box_elem, "avatar")))
                box.garbage = get_child_text(box_elem, "garbage",
                                             encode(urandom(16), "hex"))
                category = get_child_text(box_elem, "category")
                if category:
                    box.category_id = Category.by_category(category).id
                dbsession.add(box)
                dbsession.flush()
                create_flags(get_child_by_tag(box_elem, "flags"), box)
                create_hints(get_child_by_tag(box_elem, "hints"), box)
            else:
                logging.info("Box with name %s already exists, skipping" %
                             name)
        except BaseException as e:
            logging.exception("Failed to import box %d (%s)" % (index + 1, e))
Пример #21
0
 def to_xml(self, parent):
     """ Convert object to XML """
     box_elem = ET.SubElement(parent, "box")
     box_elem.set("gamelevel", "%s" % str(self.game_level.number))
     ET.SubElement(box_elem, "name").text = self.name
     ET.SubElement(box_elem,
                   "operatingsystem").text = self._operating_system
     ET.SubElement(box_elem, "description").text = self._description
     ET.SubElement(box_elem, "capture_message").text = self.capture_message
     ET.SubElement(box_elem, "value").text = str(self.value)
     ET.SubElement(box_elem,
                   "flag_submission_type").text = FlagsSubmissionType(
                       self.flag_submission_type).name
     ET.SubElement(box_elem, "difficulty").text = self._difficulty
     ET.SubElement(box_elem, "garbage").text = str(self.garbage)
     if self.category_id:
         ET.SubElement(box_elem, "category").text = Category.by_id(
             self.category_id).category
     flags_elem = ET.SubElement(box_elem, "flags")
     flags_elem.set("count", "%s" % str(len(self.flags)))
     for flag in self.flags:
         flag.to_xml(flags_elem)
     hints_elem = ET.SubElement(box_elem, "hints")
     count = 0
     for hint in self.hints:
         if hint.flag_id is None:
             hint.to_xml(hints_elem)
             count += 1
     hints_elem.set("count", "%s" % str(count))
     ips_elem = ET.SubElement(box_elem, "ipaddresses")
     ips_elem.set("count", "%s" % str(len(self.ip_addresses)))
     for ip in self.ip_addresses:
         ip.to_xml(ips_elem)
     avatarfile = os.path.join(options.avatar_dir, self.avatar)
     if self.avatar and os.path.isfile(avatarfile):
         with open(avatarfile, mode="rb") as _avatar:
             data = _avatar.read()
             ET.SubElement(box_elem, "avatar").text = encode(data, "base64")
     else:
         ET.SubElement(box_elem, "avatar").text = "none"
Пример #22
0
 def send_validate_message(self, user):
     if user is not None and len(user.email) > 0:
         email_token = encode(urandom(16), "hex")
         emailtoken = EmailToken()
         emailtoken.user_id = user.id
         emailtoken.value = sha256(email_token).hexdigest()
         receivers = [user.email]
         message = self.create_validate_message(user, email_token)
         smtpObj = smtplib.SMTP(options.mail_host, port=options.mail_port)
         smtpObj.set_debuglevel(False)
         try:
             smtpObj.starttls()
             try:
                 smtpObj.login(options.mail_username, options.mail_password)
             except smtplib.SMTPNotSupportedError as e:
                 logging.warn("SMTP Auth issue (%s). Attempting to send anyway." % e)
             smtpObj.sendmail(options.mail_sender, receivers, message)
         finally:
             smtpObj.quit()
         if not len(options.mail_host) > 0:
             logging.info(
                 "Email validation failed: No Mail Host in Configuration. Skipping Validation."
             )
             emailtoken.valid = True
         else:
             logging.info("Email Validation sent for %s" % user.email)
         self.dbsession.add(emailtoken)
         self.dbsession.commit()
     elif (
         user is not None
         and options.require_email
         and options.validate_email
         and not len(user.email) > 0
     ):
         logging.info(
             "Email validation failed: No Email Address for user %s.  Deleteing User"
             % user.handle
         )
         self.dbsession.delete(user)
         self.dbsession.commit()
Пример #23
0
 def is_valid_xid(self, box, response_xid):
     round1 = encode(sha512(encode(self.xid + box.garbage)).hexdigest())
     return response_xid == sha512(round1).hexdigest()
Пример #24
0
def get_cookie_secret():
    if options.debug:
        return "Don't use this in production"
    else:
        return encode(urandom(32), "hex")
Пример #25
0
 def get_garbage_cfg(self):
     return "[Bot]\nname = %s\ngarbage = %s\n" % (
         encode(self.name, "hex"),
         self.garbage,
     )
Пример #26
0
 def __str__(self):
     return encode(self.name, "ascii", "ignore")
Пример #27
0
 def data(self, value):
     if self.uuid is None:
         self.uuid = str(uuid4())
     self.byte_size = len(value)
     with open(options.flag_attachment_dir + "/" + self.uuid, "wb") as fp:
         fp.write(str(encode(value, "base64")).encode())
Пример #28
0
    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
"""

from os import urandom
from sqlalchemy import Column
from sqlalchemy.types import String, Boolean
from models import dbsession
from models.BaseModels import DatabaseObject
from libs.StringCoding import encode
from builtins import str

gen_token = lambda: encode(urandom(3), "hex")


class RegistrationToken(DatabaseObject):
    """ Registration token definition """

    value = Column(String(6), unique=True, nullable=False, default=gen_token)
    used = Column(Boolean, nullable=False, default=False)

    @classmethod
    def all(cls):
        """ Returns a list of all objects in the database """
        return dbsession.query(cls).all()

    @classmethod
    def by_id(cls, _id):
Пример #29
0
class Box(DatabaseObject):
    """ Box definition """

    uuid = Column(String(36),
                  unique=True,
                  nullable=False,
                  default=lambda: str(uuid4()))

    corporation_id = Column(Integer,
                            ForeignKey("corporation.id"),
                            nullable=False)

    category_id = Column(Integer, ForeignKey("category.id"), nullable=True)

    _name = Column(Unicode(32), unique=True, nullable=False)
    _operating_system = Column(Unicode(16))
    _description = Column(Unicode(1024))
    _capture_message = Column(Unicode(1024))
    _difficulty = Column(Unicode(16))
    game_level_id = Column(Integer,
                           ForeignKey("game_level.id"),
                           nullable=False)
    _avatar = Column(String(64))
    _value = Column(Integer, nullable=True)
    _locked = Column(Boolean, default=False, nullable=False)

    garbage = Column(
        String(32),
        unique=True,
        nullable=False,
        default=lambda: encode(urandom(16), "hex"),
    )

    teams = relationship("Team",
                         secondary=team_to_box,
                         backref=backref("box", lazy="select"))

    hints = relationship(
        "Hint",
        backref=backref("box", lazy="select"),
        cascade="all,delete,delete-orphan",
    )

    flags = relationship(
        "Flag",
        backref=backref("box", lazy="select"),
        cascade="all,delete,delete-orphan",
        order_by="desc(-Flag._order)",
    )

    flag_submission_type = Column(Enum(FlagsSubmissionType),
                                  default=FlagsSubmissionType.CLASSIC)

    ip_addresses = relationship(
        "IpAddress",
        backref=backref("box", lazy="select"),
        cascade="all,delete,delete-orphan",
    )

    @classmethod
    def all(cls):
        """ Returns a list of all objects in the database """
        return dbsession.query(cls).all()

    @classmethod
    def by_id(cls, _id):
        """ Returns a the object with id of _id """
        return dbsession.query(cls).filter_by(id=_id).first()

    @classmethod
    def by_uuid(cls, _uuid):
        """ Return and object based on a uuid """
        return dbsession.query(cls).filter_by(uuid=str(_uuid)).first()

    @classmethod
    def by_name(cls, name):
        """ Return the box object whose name is "name" """
        return dbsession.query(cls).filter_by(_name=str(name)).first()

    @classmethod
    def by_category(cls, _cat_id):
        """ Return the box object whose category is "_cat_id" """
        return dbsession.query(cls).filter_by(category_id=int(_cat_id)).all()

    @classmethod
    def by_garbage(cls, _garbage):
        return dbsession.query(cls).filter_by(garbage=_garbage).first()

    @classmethod
    def by_ip_address(cls, ip_addr):
        """
        Returns a box object based on an ip address, supports both ipv4
        and ipv6
        """
        ip = IpAddress.by_address(ip_addr)

        return ip.box if ip is not None else None

    @classmethod
    def flaglist(self, box_id=None):
        flags = self.by_id(box_id).flags
        flaglist = OrderedDict()
        for flag in flags:
            flaglist[flag.uuid] = flag.name
        return flaglist

    @property
    def name(self):
        return self._name

    @name.setter
    def name(self, value):
        if not 3 <= len(str(value)) <= 32:
            raise ValidationError("Name must be 3 - 32 characters")
        self._name = str(value)

    @property
    def operating_system(self):
        return self._operating_system if self._operating_system else "?"

    @operating_system.setter
    def operating_system(self, value):
        self._operating_system = str(value)

    @property
    def description(self):
        if self._description is None:
            self._description = ""
        ls = []
        if 0 < len(self._description):
            text = self._description.replace("\r\n", "\n").strip()
            ls.append("%s" % text)
        else:
            ls.append("No information on file.")
        if self.difficulty != "Unknown":
            ls.append("Reported Difficulty: %s" % self.difficulty)
        if not encode(ls[-1], "utf-8").endswith(b"\n"):
            ls[-1] = ls[-1] + "\n"
        return str("\n\n".join(ls))

    @description.setter
    def description(self, value):
        if value is None:
            return ""
        if 1025 < len(value):
            raise ValidationError(
                "Description cannot be greater than 1024 characters")
        self._description = str(value)

    @property
    def difficulty(self):
        return (self._difficulty
                if self._difficulty and len(self._difficulty) else "Unknown")

    @difficulty.setter
    def difficulty(self, value):
        if value is None:
            return
        if 17 < len(value):
            raise ValidationError(
                "Difficulty cannot be greater than 16 characters")
        self._difficulty = str(value)

    @property
    def capture_message(self):
        return self._capture_message if self._capture_message else ""

    @capture_message.setter
    def capture_message(self, value):
        self._capture_message = str(value)

    @property
    def value(self):
        if not self._value:
            return 0
        return self._value

    @value.setter
    def value(self, value):
        try:
            self._value = abs(int(value))
        except ValueError:
            raise ValidationError("Reward value must be an integer")

    @property
    def locked(self):
        """ Determines if an admin has locked an box. """
        return self._locked

    @locked.setter
    def locked(self, value):
        """ Setter method for _lock """
        assert isinstance(value, bool)
        self._locked = value

    @property
    def avatar(self):
        if self._avatar is not None:
            return self._avatar
        else:
            avatar = get_new_avatar("box")
            if not avatar.startswith("default_"):
                self._avatar = avatar
                dbsession.add(self)
                dbsession.commit()
            return avatar

    @avatar.setter
    def avatar(self, image_data):
        if self.uuid is None:
            self.uuid = str(uuid4())
        if len(image_data) < (1024 * 1024):
            ext = imghdr.what("", h=image_data)
            if ext in ["png", "jpeg", "gif", "bmp"
                       ] and not is_xss_image(image_data):
                try:
                    if self._avatar is not None and os.path.exists(
                            options.avatar_dir + "/upload/" + self._avatar):
                        os.unlink(options.avatar_dir + "/upload/" +
                                  self._avatar)
                    file_path = str(options.avatar_dir + "/upload/" +
                                    self.uuid + "." + ext)
                    image = Image.open(io.BytesIO(image_data))
                    cover = resizeimage.resize_cover(image, [500, 250])
                    cover.save(file_path, image.format)
                    self._avatar = "upload/" + self.uuid + "." + ext
                except Exception as e:
                    raise ValidationError(e)
            else:
                raise ValidationError(
                    "Invalid image format, avatar must be: .png .jpeg .gif or .bmp"
                )
        else:
            raise ValidationError("The image is too large")

    @property
    def ipv4s(self):
        """ Return a list of all ipv4 addresses """
        return [ip for ip in self.ip_addresses if ip.version == 4]

    @property
    def ipv6s(self):
        """ Return a list of all ipv6 addresses """
        return [ip for ip in self.ip_addresses if ip.version == 6]

    @property
    def visable_ips(self):
        return [ip for ip in self.ip_addresses if ip.visable is True]

    @property
    def source_code(self):
        return SourceCode.by_box_id(self.id)

    def get_garbage_cfg(self):
        try:
            hex_name = encode(self.name).hex()
        except AttributeError:
            hex_name = encode(self.name, "hex")
        return "[Bot]\nname = %s\ngarbage = %s\n" % (hex_name, self.garbage)

    def is_complete(self, user):
        boxcomplete = True
        for boxflag in self.flags:
            if user.team and boxflag not in user.team.flags:
                boxcomplete = False
                break
        return boxcomplete

    def to_xml(self, parent):
        """ Convert object to XML """
        box_elem = ET.SubElement(parent, "box")
        box_elem.set("gamelevel", "%s" % str(self.game_level.number))
        ET.SubElement(box_elem, "name").text = self.name
        ET.SubElement(box_elem,
                      "operatingsystem").text = self._operating_system
        ET.SubElement(box_elem, "description").text = self._description
        ET.SubElement(box_elem, "capture_message").text = self.capture_message
        ET.SubElement(box_elem, "value").text = str(self.value)
        ET.SubElement(box_elem,
                      "flag_submission_type").text = FlagsSubmissionType(
                          self.flag_submission_type).name
        ET.SubElement(box_elem, "difficulty").text = self._difficulty
        ET.SubElement(box_elem, "garbage").text = str(self.garbage)
        if self.category_id:
            ET.SubElement(box_elem, "category").text = Category.by_id(
                self.category_id).category
        flags_elem = ET.SubElement(box_elem, "flags")
        flags_elem.set("count", "%s" % str(len(self.flags)))
        for flag in self.flags:
            flag.to_xml(flags_elem)
        hints_elem = ET.SubElement(box_elem, "hints")
        count = 0
        for hint in self.hints:
            if hint.flag_id is None:
                hint.to_xml(hints_elem)
                count += 1
        hints_elem.set("count", "%s" % str(count))
        ips_elem = ET.SubElement(box_elem, "ipaddresses")
        ips_elem.set("count", "%s" % str(len(self.ip_addresses)))
        for ip in self.ip_addresses:
            ip.to_xml(ips_elem)
        avatarfile = os.path.join(options.avatar_dir, self.avatar)
        if self.avatar and os.path.isfile(avatarfile):
            with open(avatarfile, mode="rb") as _avatar:
                data = _avatar.read()
                ET.SubElement(box_elem, "avatar").text = encode(data, "base64")
        else:
            ET.SubElement(box_elem, "avatar").text = "none"

    def to_dict(self):
        """ Returns editable data as a dictionary """
        corp = Corporation.by_id(self.corporation_id)
        game_level = GameLevel.by_id(self.game_level_id)
        cat = Category.by_id(self.category_id)
        if cat:
            category = cat.uuid
        else:
            category = ""
        return {
            "name": self.name,
            "uuid": self.uuid,
            "corporation": corp.uuid,
            "category": category,
            "operating_system": self.operating_system,
            "description": self._description,
            "capture_message": self.capture_message,
            "difficulty": self.difficulty,
            "game_level": game_level.uuid,
            "flag_submission_type": self.flag_submission_type,
            "flaglist": self.flaglist(self.id),
            "value": self.value,
        }

    def __repr__(self):
        return "<Box - name: %s>" % (self.name, )

    def __str__(self):
        return self.name
Пример #30
0
 def get_garbage_cfg(self):
     try:
         hex_name = encode(self.name).hex()
     except AttributeError:
         hex_name = encode(self.name, "hex")
     return "[Bot]\nname = %s\ngarbage = %s\n" % (hex_name, self.garbage)