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")
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()
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()
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)
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."], )
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."], )
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")
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}
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())
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"))
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")
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")
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()
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
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 }
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))
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)
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)
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")
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))
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 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()
def is_valid_xid(self, box, response_xid): round1 = encode(sha512(encode(self.xid + box.garbage)).hexdigest()) return response_xid == sha512(round1).hexdigest()
def get_cookie_secret(): if options.debug: return "Don't use this in production" else: return encode(urandom(32), "hex")
def get_garbage_cfg(self): return "[Bot]\nname = %s\ngarbage = %s\n" % ( encode(self.name, "hex"), self.garbage, )
def __str__(self): return encode(self.name, "ascii", "ignore")
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())
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):
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
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)