示例#1
0
 def data(self, value):
     config = ConfigManager.instance()
     if self.uuid is None:
         self.uuid = str(uuid4())
     self.byte_size = len(value)
     with open(config.file_uploads_dir + self.uuid, 'wb') as fp:
         fp.write(value.encode('base64'))
示例#2
0
 def __init__(self):
     self.config = ConfigManager.instance()
     self.dbsession = dbsession
     self.cache = pylibmc.Client([self.config.memcached], binary=True)
     self.epoch = None  # Date/time of first snapshot
     self._load()
     self.event_manager = EventManager.instance()
示例#3
0
 def post(self, *args, **kwargs):
     '''
     Update configuration
     Disabled fields will not be send in the POST, so check for blank values
     '''
     try:
         config = ConfigManager.instance()
         config.game_name = self.get_argument('game_name', '')
         config.restrict_registration = self.get_argument('restrict_registration', '') == 'true'
         config.public_teams = self.get_argument('public_teams', '') == 'true'
         config.max_team_size = self.get_argument('max_team_size', '')
         config.max_password_length = self.get_argument('max_password_length', '')
         self.config_bots(config)
         reward = self.get_argument('bot_reward', '')
         if reward != '':
             config.bot_reward = reward
         config.use_black_market = self.get_argument('use_black_market', '') == 'true'
         upgrade_cost = self.get_argument('password_upgrade_cost', '')
         if upgrade_cost != '':
             config.password_upgrade_cost = upgrade_cost
         bribe_cost = self.get_argument('bribe_cost', '')
         if bribe_cost != '':
             config.bribe_cost = bribe_cost
         config.save()
         self.render('admin/configuration.html', errors=None, config=self.config)
     except Exception as error:
         logging.exception("Configuration update threw an exception")
         self.render('admin/configuration.html', errors=[str(error)], config=self.config)
示例#4
0
 def to_xml(self, parent):
     ''' Convert object to XML '''
     box_elem = ET.SubElement(parent, "box")
     box_elem.set("gamelevel", 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, "difficulty").text = self._difficulty
     ET.SubElement(box_elem, "garbage").text = self.garbage
     flags_elem = ET.SubElement(box_elem, "flags")
     flags_elem.set("count", str(len(self.flags)))
     for flag in self.flags:
         flag.to_xml(flags_elem)
     hints_elem = ET.SubElement(box_elem, "hints")
     hints_elem.set("count", str(len(self.hints)))
     for hint in self.hints:
         hint.to_xml(hints_elem)
     ips_elem = ET.SubElement(box_elem, "ipaddresses")
     ips_elem.set("count", str(len(self.ips)))
     for ip in self.ips:
         ip.to_xml(ips_elem)
     config = ConfigManager.instance()
     with open(config.avatar_dir + self.avatar) as favatar:
         data = favatar.read()
         ET.SubElement(box_elem, "avatar").text = data.encode('base64')
示例#5
0
def score_bots():
    ''' Award money for botnets '''
    logging.info("Scoring botnets, please wait ...")
    bot_manager = BotManager.instance()
    config = ConfigManager.instance()
    for team in Team.all():
        bots = bot_manager.by_team(team.name)
        reward = 0
        for bot in bots:
            try:
                reward += config.bot_reward
                bot.write_message({
                    'opcode':
                    'status',
                    'message':
                    'Collected $%d reward' % config.bot_reward
                })
            except:
                logging.info("Bot at %s failed to respond to score ping" %
                             bot.remote_ip)
        if 0 < len(bots):
            logging.info("%s was awarded $%d for controlling %s bot(s)" % (
                team.name,
                reward,
                len(bots),
            ))
            bot_manager.add_rewards(team.name, config.bot_reward)
            bot_manager.notify_monitors(team.name)
            team.money += reward
            dbsession.add(team)
            dbsession.flush()
    dbsession.commit()
示例#6
0
 def data(self, value):
     config = ConfigManager.instance()
     if self.uuid is None:
         self.uuid = str(uuid4())
     self.byte_size = len(value)
     with open(config.file_uploads_dir + self.uuid, 'wb') as fp:
         fp.write(value.encode('base64'))
示例#7
0
 def to_xml(self, parent):
     ''' Convert object to XML '''
     box_elem = ET.SubElement(parent, "box")
     box_elem.set("gamelevel", 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, "difficulty").text = self._difficulty
     ET.SubElement(box_elem, "garbage").text = self.garbage
     flags_elem = ET.SubElement(box_elem, "flags")
     flags_elem.set("count", str(len(self.flags)))
     for flag in self.flags:
         flag.to_xml(flags_elem)
     hints_elem = ET.SubElement(box_elem, "hints")
     hints_elem.set("count", str(len(self.hints)))
     for hint in self.hints:
         hint.to_xml(hints_elem)
     ips_elem = ET.SubElement(box_elem, "ipaddresses")
     ips_elem.set("count", str(len(self.ips)))
     for ip in self.ips:
         ip.to_xml(ips_elem)
     config = ConfigManager.instance()
     with open(config.avatar_dir + self.avatar) as favatar:
         data = favatar.read()
         ET.SubElement(box_elem, "avatar").text = data.encode('base64')
示例#8
0
class StaticFileHandler(DefaultStaticHandler):
    '''
    Same as the normal Tornado StaticFileHandler with a
    couple overloaded methods.
    '''

    session = None
    config = ConfigManager.instance()

    def set_default_headers(self):
        '''
        We need to add the security headers here too, especially the
        X-Content-Type-Options header, since we whitelist file extenstions.
        this should prevent anyone from serving html/etc from the static handler
        '''
        self.set_header("Server", "Microsoft-IIS/7.5")
        self.add_header("X-AspNetMvc-Version", "3.0")
        self.add_header("X-AspNet-Version", "4.0.30319")
        self.add_header("X-Powered-By", "ASP.NET")
        self.add_header("X-Frame-Options", "DENY")
        self.add_header("X-XSS-Protection", "1; mode=block")
        self.add_header("X-Content-Type-Options", "nosniff")
        if self.config.use_ssl:
            self.add_header("Strict-Transport-Security",
                            'max-age=31536000; includeSubDomains;')

    def write_error(self, status_code, **kwargs):
        ''' Render a generic error page '''
        logging.error("Static file request from %s resulted in %d status" %
                      (self.request.remote_ip, status_code))
        # Reguardless of error, send a 404
        self.render('public/404.html')
 def initialize(self):
     ''' Setup sessions, etc '''
     self.session = None
     self.config = ConfigManager.instance()
     session_id = self.get_secure_cookie('session_id')
     if session_id is not None:
         self.session = self._create_session(session_id)
         self.session.refresh()
示例#10
0
 def _registration_post_token(self, form):
     config_manager = ConfigManager.instance()
     config_manager.restrict_registration = True
     form["token"] = "NotARealRegToken"
     self.post("/registration", data=form)(self.stop)
     rsp, body = self.wait()
     assert "Invalid registration token" in body
     config_manager.restrict_registration = False
示例#11
0
 def _registration_post_token(self, form):
     config_manager = ConfigManager.instance()
     config_manager.restrict_registration = True
     form['token'] = 'NotARealRegToken'
     self.post('/registration', data=form)(self.stop)
     rsp, body = self.wait()
     assert "Invalid registration token" in body
     config_manager.restrict_registration = False
示例#12
0
 def initialize(self):
     ''' Setup sessions, etc '''
     self.session = None
     self.config = ConfigManager.instance()
     self.loader = template.Loader("templates/")
     session_id = self.get_secure_cookie('session_id')
     if session_id is not None:
         self.session = self._create_session(session_id)
         self.session.refresh()
示例#13
0
 def initialize(self):
     self.config = ConfigManager.instance()
     self.bot_manager = BotManager.instance()
     self.team_name = None
     if not self.config.use_bots:
         self.close()
     else:
         self.uuid = unicode(uuid4())
         self.opcodes = {"auth": self.auth}
示例#14
0
 def __init__(self):
     config = ConfigManager.instance()
     self.botnet = {}  # Holds refs to wsockets
     self.monitors = {}
     self.sqlite_engine = create_engine(u'sqlite://')
     setattr(self.sqlite_engine, 'echo', config.bot_sql)
     Session = sessionmaker(bind=self.sqlite_engine, autocommit=True)
     self.botdb = Session(autoflush=True)
     MemoryBaseObject.metadata.create_all(self.sqlite_engine)
     self.dbsession = dbsession
示例#15
0
 def render(self, *args, **kwargs):
     ''' Includes different CSS themes based on user prefs '''
     if self.handler.session is not None:
         return self.render_string("theme/css.html",
             theme=self.handler.session['theme']
         )
     else:
         config = ConfigManager.instance()
         default_theme = config.default_theme
         return self.render_string("theme/css.html", theme=default_theme)
示例#16
0
 def __init__(self):
     config = ConfigManager.instance()
     self.botnet = {}  # Holds refs to wsockets
     self.monitors = {}
     self.sqlite_engine = create_engine(u'sqlite://')
     setattr(self.sqlite_engine, 'echo', config.bot_sql)
     Session = sessionmaker(bind=self.sqlite_engine, autocommit=True)
     self.botdb = Session(autoflush=True)
     MemoryBaseObject.metadata.create_all(self.sqlite_engine)
     self.dbsession = dbsession
示例#17
0
 def initialize(self):
     ''' Setup sessions, etc '''
     self.session = None
     self.config = ConfigManager.instance()
     session_id = self.get_secure_cookie('session_id')
     if session_id is not None:
         self.conn = pylibmc.Client([self.config.memcached], binary=True)
         self.conn.behaviors['no_block'] = 1  # async I/O
         self.session = self._create_session(session_id)
         self.session.refresh()
示例#18
0
 def initialize(self):
     """ Setup sessions, etc """
     self.session = None
     self._dbsession = dbsession
     self.new_events = []
     self.event_manager = self.application.settings["event_manager"]
     self.config = ConfigManager.instance()
     session_id = self.get_secure_cookie("session_id")
     if session_id is not None:
         self.session = self._create_session(session_id)
         self.session.refresh()
示例#19
0
 def initialize(self):
     """ Setup sessions, etc """
     self.session = None
     self.manager = EventManager.instance()
     self.config = ConfigManager.instance()
     session_id = self.get_secure_cookie("session_id")
     if session_id is not None:
         self.conn = pylibmc.Client([self.config.memcached], binary=True)
         self.conn.behaviors["no_block"] = 1  # async I/O
         self.session = self._create_session(session_id)
         self.session.refresh()
示例#20
0
def setup_database(db_name):
    # Setup the test database
    logging.debug("Setting up the test database connection ...")
    config_manager = ConfigManager.instance()
    config_manager.db_connection = 'sqlite:///%s.db' % db_name
    assert config_manager.db_connection == 'sqlite:///%s.db' % db_name

    # Create the default tables
    logging.debug("Creating tables ... ")
    from setup.create_database import create_tables, engine, metadata
    create_tables(engine, metadata, False)
    import setup.bootstrap
示例#21
0
def setup_database(db_name):
    # Setup the test database
    logging.debug("Setting up the test database connection ...")
    config_manager = ConfigManager.instance()
    config_manager.db_connection = 'sqlite:///%s.db' % db_name
    assert config_manager.db_connection == 'sqlite:///%s.db' % db_name

    # Create the default tables
    logging.debug("Creating tables ... ")
    from setup.create_database import create_tables, engine, metadata
    create_tables(engine, metadata, False)
    import setup.bootstrap
示例#22
0
 def initialize(self):
     self.bot_manager = BotManager.instance()
     self.event_manager = EventManager.instance()
     self.config = ConfigManager.instance()
     self.team_name = None
     self.team_uuid = None
     self.box_uuid = None
     self.remote_ip = None
     self.xid = os.urandom(16).encode("hex")
     if not self.config.use_bots:
         self.close()
     else:
         self.uuid = unicode(uuid4())
         self.opcodes = {"interrogation_response": self.interrogation_response}
示例#23
0
 def avatar(self, image_data):
     if len(image_data) < (1024 * 1024):
         ext = imghdr.what("", h=image_data)
         if ext in ['png', 'jpeg', 'gif', 'bmp']:
             config = ConfigManager.instance()
             if self._avatar is not None and os.path.exists(config.avatar_dir + self._avatar):
                 os.unlink(config.avatar_dir + self._avatar)
             file_path = str(config.avatar_dir + self.uuid + '.' + ext)
             with open(file_path, 'wb') as fp:
                 fp.write(image_data)
             self._avatar = self.uuid + '.' + ext
         else:
             raise ValueError("Invalid image format, avatar must be: .png .jpeg .gif or .bmp")
     else:
         raise ValueError("The image is too large")
示例#24
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.has_permission(ADMIN_PERMISSION):
         user_elem = ET.SubElement(parent, "user")
         ET.SubElement(user_elem, "handle").text = self.handle
         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)
         config = ConfigManager.instance()
         with open(config.avatar_dir + self.avatar) as fp:
             data = fp.read()
             ET.SubElement(user_elem, "avatar").text = data.encode('base64')
示例#25
0
class FirstLoginHandler(BaseHandler):

    # Terminal JS needs eval()
    relaxed_csp = "default-src 'self';" + \
        "script-src 'self' 'unsafe-eval';" + \
        "style-src 'self' 'unsafe-inline';" + \
        "font-src 'self';" + \
        "img-src 'self';" + \
        "connect-src 'self' %s" % ConfigManager.instance().ws_connect

    @authenticated
    def get(self, *args, **kwargs):
        user = self.get_current_user()
        reward = self.config.bot_reward
        self.set_header("Content-Security-Policy", self.relaxed_csp)
        self.render('missions/firstlogin.html', reward=reward, user=user)
示例#26
0
def create():
    ''' Creates/bootstraps the database '''
    from libs.ConfigManager import ConfigManager  # Sets up logging
    print(INFO+'%s : Creating the database ...' % current_time())
    from setup.create_database import create_tables, engine, metadata
    dev = ConfigManager.instance().bootstrap == 'developement'
    create_tables(engine, metadata, dev)
    print(INFO+'%s : Bootstrapping the database ...' % current_time())
    import setup.bootstrap
    # Display Details
    if dev:
        environ = bold + R + "Developement boot strap" + W
        details = ", admin password is 'nimda123'."
    else:
        environ = bold + "Production boot strap" + W
        details = '.'
    print INFO + '%s completed successfully%s' % (environ, details)
示例#27
0
def create():
    ''' Creates/bootstraps the database '''
    from libs.ConfigManager import ConfigManager  # Sets up logging
    print(INFO + '%s : Creating the database ...' % current_time())
    from setup.create_database import create_tables, engine, metadata
    is_devel = ConfigManager.instance().bootstrap.startswith('dev')
    create_tables(engine, metadata, is_devel)
    print(INFO + '%s : Bootstrapping the database ...' % current_time())
    import setup.bootstrap
    # Display Details
    if is_devel:
        environ = bold + R + "Developement boot strap" + W
        details = ", admin password is 'nimda123'."
    else:
        environ = bold + "Production boot strap" + W
        details = '.'
    print(INFO + '%s completed successfully%s' % (environ, details))
示例#28
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.
     '''
     config = ConfigManager.instance()
     password = filter(lambda char: char in printable[:-6], password)
     if config.max_password_length < len(password):
         raise ValueError("Bank password is too long")
     if algorithm_name is None:
         algorithm_name = DEFAULT_HASH_ALGORITHM
     if algorithm_name in cls.algorithms:
         algo = cls.algorithms[algorithm_name][0]()
         algo.update(password)
         return algo.hexdigest()
     else:
         raise ValueError("Algorithm %s not supported." % algorithm_name)
示例#29
0
def score_bots():
    """ Award money for botnets """
    logging.info("Scoring botnets, please wait ...")
    bot_manager = BotManager.instance()
    config = ConfigManager.instance()
    for team in Team.all():
        bots = bot_manager.by_team(team.name)
        reward = 0
        for bot in bots:
            try:
                reward += config.bot_reward
                bot.write_message({"opcode": "status", "message": "Collected $%d reward" % config.bot_reward})
            except:
                logging.info("Bot at %s failed to respond to score ping" % bot.remote_ip)
        if 0 < len(bots):
            logging.info("%s was awarded $%d for controlling %s bot(s)" % (team.name, reward, len(bots)))
            bot_manager.add_rewards(team.name, config.bot_reward)
            bot_manager.notify_monitors(team.name)
            team.money += reward
            dbsession.add(team)
            dbsession.flush()
    dbsession.commit()
示例#30
0
 def attempt_capture(self, flag, submission):
     ''' Compares a user provided token to the token in the db '''
     user = self.get_current_user()
     logging.info("%s (%s) capture the flag '%s'" %
                  (user.handle, user.team.name, flag.name))
     if submission is not None and flag not in user.team.flags:
         if flag.capture(submission):
             user.team.flags.append(flag)
             user.team.money += flag.value
             self.dbsession.add(user.team)
             config = ConfigManager.instance()
             if config.dynamic_flag_value:
                 flag.value = int(flag.value - (
                     (flag.value / config.flag_value_decrease) / 100))
             self.dbsession.add(flag)
             self.dbsession.flush()
             event = self.event_manager.create_flag_capture_event(
                 user, flag)
             self.new_events.append(event)
             self._check_level(flag)
             self.dbsession.commit()
             return True
     return False
示例#31
0
 def get_price(cls, user):
     ''' Calculate price of next bribe based on history '''
     config = ConfigManager.instance()
     base_price = config.bribe_cost
     return base_price + (cls.count_completed_by_target_id(user.id) * base_price)
示例#32
0
 def data(self):
     config = ConfigManager.instance()
     with open(config.file_uploads_dir + self.uuid, 'rb') as fp:
         return fp.read().decode('base64')
示例#33
0
 def get_organizations_from_file():
     ''' Gets the JSON object containing an org list from the configured file '''
     config = ConfigManager.instance()
     with open(config.fb_organization_file, 'r') as f:
         return json.loads(f.read())
示例#34
0
class FlagSubmissionHandler(BaseHandler):

    # Terminal JS needs eval()
    relaxed_csp = "default-src 'self';" + \
        "script-src 'self' 'unsafe-eval';" + \
        "style-src 'self' 'unsafe-inline';" + \
        "font-src 'self';" + \
        "img-src 'self';" + \
        "connect-src 'self' %s" % ConfigManager.instance().ws_connect

    @authenticated
    def post(self, *args, **kwargs):
        ''' Check validity of flag submissions '''
        flag = Flag.by_uuid(self.get_argument('uuid', ''))
        user = self.get_current_user()
        if flag is not None and flag.game_level in user.team.game_levels:
            if flag.is_file and 'flag' in self.request.files:
                submission = self.request.files['flag'][0]['body']
            elif not flag.is_file:
                submission = self.get_argument('token', '')
            else:
                submission = None
            old_reward = flag.value
            if self.attempt_capture(flag, submission):
                self.set_header("Content-Security-Policy", self.relaxed_csp)
                self.render('missions/captured.html', flag=flag, reward=old_reward)
            else:
                self.render_page(flag, errors=["Invalid flag submission"])
        else:
            self.render('public/404.html')

    def attempt_capture(self, flag, submission):
        ''' Compares a user provided token to the token in the db '''
        user = self.get_current_user()
        logging.info("%s (%s) capture the flag '%s'" % (
            user.handle, user.team.name, flag.name
        ))
        if submission is not None and flag not in user.team.flags:
            if flag.capture(submission):
                user.team.flags.append(flag)
                user.team.money += flag.value
                self.dbsession.add(user.team)
                flag.value = int(flag.value * 0.90)
                self.dbsession.add(flag)
                self.dbsession.flush()
                event = self.event_manager.create_flag_capture_event(user, flag)
                self.new_events.append(event)
                self._check_level(flag)
                self.dbsession.commit()
                return True
        return False

    def _check_level(self, flag):
        user = self.get_current_user()
        if len(user.team.level_flags(flag.game_level.number)) == len(flag.game_level.flags):
            next_level = flag.game_level.next()
            logging.info("Next level is %r" % next_level)
            if next_level is not None and next_level not in user.team.game_levels:
                logging.info("Team completed level, unlocking the next level")
                user.team.game_levels.append(next_level)
                self.dbsession.add(user.team)

    def render_page(self, flag, errors=[]):
        ''' Wrapper to .render() to avoid duplicate code '''
        user = self.get_current_user()
        box = Box.by_id(flag.box_id)
        self.render('missions/box.html',
            box=box,
            team=user.team,
            errors=errors,
        )
示例#35
0
 def get_price(cls, user):
     ''' Calculate price of next bribe based on history '''
     config = ConfigManager.instance()
     base_price = config.bribe_cost
     return base_price + (cls.count_completed_by_target_id(user.id) *
                          base_price)
示例#36
0
 def data(self):
     config = ConfigManager.instance()
     with open(config.file_uploads_dir + self.uuid, 'rb') as fp:
         return fp.read().decode('base64')
示例#37
0
 def delete_data(self):
     config = ConfigManager.instance()
     if os.path.exists(config.file_uploads_dir + self.uuid):
         os.unlink(config.file_uploads_dir + self.uuid)
示例#38
0
 def wrapper(self, *args, **kwargs):
     if ConfigManager.instance().use_black_market:
         return method(self, *args, **kwargs)
     else:
         self.render('public/404.html')
示例#39
0
class BaseWebSocketHandler(WebSocketHandler):
    ''' Handles websocket connections '''

    _session = None
    _memcached = None
    io_loop = IOLoop.instance()
    manager = EventManager.instance()
    config = ConfigManager.instance()

    @property
    def memcached(self):
        ''' Connects to Memcached instance '''
        if self._memcached is None:
            self._memcached = pylibmc.Client([self.config.memcached], binary=True)
            self._memcached.behaviors['no_block'] = 1  # async I/O
        return self._memcached

    @property
    def session(self):
        if self._session is None:
            session_id = self.get_secure_cookie('session_id')
            if session_id is not None:
                self._session = self._get_session(session_id)
        return self._session

    @session.setter
    def session(self, new_session):
        self._session = new_session

    def _get_session(self, session_id):
        kwargs = {
            'connection': self.memcached,
            'session_id': session_id,
            'ip_address': self.request.remote_ip,
        }
        old_session = MemcachedSession.load(**kwargs)
        if old_session and not old_session.is_expired():
            old_session.refresh()
            return old_session
        else:
            return None

    def get_current_user(self):
        ''' Get current user object from database '''
        if self.session is not None:
            try:
                return User.by_handle(self.session['handle'])
            except KeyError:
                logging.exception(
                    "Malformed session: %r" % self.session
                )
            except:
                logging.exception("Failed call to get_current_user()")
        return None

    def open(self):
        pass

    def on_message(self, message):
        pass

    def on_close(self):
        pass
示例#40
0
 def initialize(self):
     self.config = ConfigManager.instance()
     if not self.config.use_bots:
         self.close()
示例#41
0
class BaseHandler(RequestHandler):
    ''' User handlers extend this class '''

    csp = {
        "default-src": set(["'self'"]),
        "script-src": set(["'self'"]),
        "connect-src": set(["'self'"]),
        "frame-src": set(["'self'"]),
        "img-src": set(["'self'"]),
        "media-src": set(["'self'"]),
        "font-src": set(["'self'"]),
        "object-src": set(["'self'"]),
        "style-src": set(["'self'"]),
    }
    _session = None
    _dbsession = dbsession
    _memcached = None
    new_events = []
    io_loop = IOLoop.instance()
    event_manager = EventManager.instance()
    config = ConfigManager.instance()

    def initialize(self):
        ''' Setup sessions, etc '''
        self.add_content_policy('connect-src', self.config.ws_connect)
        # We need this for a few things, and so far as I know it doesn't present
        # too much of a security risk - TODO: no longer require inline styles
        self.add_content_policy('style-src', "'unsafe-inline'")
        # This add unsafe eval to script src header 
        # -> CSP problem & use of console commands. 
        self.add_content_policy('script-src', "'unsafe-eval'")

    @property
    def dbsession(self):
        return self._dbsession

    def get_current_user(self):
        ''' Get current user object from database '''
        if self.session is not None:
            try:
                return User.by_uuid(self.session['user_uuid'])
            except KeyError:
                logging.exception("Malformed session: %r" % self.session)
            except:
                logging.exception("Failed call to get_current_user()")
        return None

    def start_session(self):
        ''' Starts a new session '''
        self.session = self._create_session()
        self.set_secure_cookie('session_id',
            self.session.session_id,
            expires=self.session.expires,
            path='/',
            HttpOnly=True,
        )

    def add_content_policy(self, src, policy):
        ''' Add to the existing CSP header '''
        if src in self.csp:
            self.csp[src].add(policy)
            self._refresh_csp()
        else:
            raise ValueError("Invalid content source")

    def clear_content_policy(self, src):
        ''' Clear a content source in the existing CSP header '''
        if src in self.csp:
            self.csp[src] = set()
            self._refresh_csp()
        else:
            raise ValueError("Invalid content source")

    def _refresh_csp(self):
        ''' Rebuild the Content-Security-Policy header '''
        _csp = ''
        for src, policies in self.csp.iteritems():
            if len(policies):
                _csp += "%s %s; " % (src, " ".join(policies))
        self.set_header("Content-Security-Policy", _csp)

    @property
    def memcached(self):
        ''' Connects to Memcached instance '''
        if self._memcached is None:
            self._memcached = pylibmc.Client([self.config.memcached], binary=True)
            self._memcached.behaviors['no_block'] = 1  # async I/O
        return self._memcached

    def _create_session(self):
        ''' Creates a new session '''
        kwargs = {
            'connection': self.memcached,
            'ip_address': self.request.remote_ip,
        }
        new_session = MemcachedSession(**kwargs)
        new_session.save()
        return new_session

    @property
    def session(self):
        if self._session is None:
            session_id = self.get_secure_cookie('session_id')
            if session_id is not None:
                self._session = self._get_session(session_id)
        return self._session

    @session.setter
    def session(self, new_session):
        self._session = new_session

    def _get_session(self, session_id):
        kwargs = {
            'connection': self.memcached,
            'session_id': session_id,
            'ip_address': self.request.remote_ip,
        }
        old_session = MemcachedSession.load(**kwargs)
        if old_session and not old_session.is_expired():
            old_session.refresh()
            return old_session
        else:
            return None

    def set_default_headers(self):
        '''
        Set security HTTP headers, and add some troll-y version headers
        '''
        self.set_header("Server", "Microsoft-IIS/7.5")
        self.add_header("X-AspNetMvc-Version", "3.0")
        self.add_header("X-AspNet-Version", "4.0.30319")
        self.add_header("X-Powered-By", "ASP.NET")
        self.add_header("X-Frame-Options", "DENY")
        self.add_header("X-XSS-Protection", "1; mode=block")
        self.add_header("X-Content-Type-Options", "nosniff")
        self._refresh_csp()
        if self.config.use_ssl:
            self.add_header("Strict-Transport-Security", '"max-age=31536000; includeSubDomains";')

    def write_error(self, status_code, **kwargs):
        ''' Write our custom error pages '''
        if not self.config.debug:
            trace = "".join(traceback.format_exception(*kwargs["exc_info"]))
            logging.error("Request from %s resulted in an error code %d:\n%s" % (
                self.request.remote_ip, status_code, trace
            ))
            if status_code in [403]:
                # This should only get called when the _xsrf check fails,
                # all other '403' cases we just send a redirect to /403
                self.render('public/403.html', locked=False, xsrf=True)
            else:
                # Never tell the user we got a 500
                self.render('public/404.html')
        else:
            # If debug mode is enabled, just call Tornado's write_error()
            super(BaseHandler, self).write_error(status_code, **kwargs)

    @property
    def dbsession(self):
        return self._dbsession

    def get(self, *args, **kwargs):
        ''' Placeholder, incase child class does not impl this method '''
        self.render("public/404.html")

    def post(self, *args, **kwargs):
        ''' Placeholder, incase child class does not impl this method '''
        self.render("public/404.html")

    def put(self, *args, **kwargs):
        ''' Log odd behavior, this should never get legitimately called '''
        logging.warn(
            "%s attempted to use PUT method" % self.request.remote_ip
        )

    def delete(self, *args, **kwargs):
        ''' Log odd behavior, this should never get legitimately called '''
        logging.warn(
            "%s attempted to use DELETE method" % self.request.remote_ip
        )

    def head(self, *args, **kwargs):
        ''' Ignore it '''
        logging.warn(
            "%s attempted to use HEAD method" % self.request.remote_ip
        )

    def options(self, *args, **kwargs):
        ''' Log odd behavior, this should never get legitimately called '''
        logging.warn(
            "%s attempted to use OPTIONS method" % self.request.remote_ip
        )

    def on_finish(self, *args, **kwargs):
        ''' Called after a response is sent to the client '''
        self._dbsession.close()
        if 0 < len(self.new_events):
            self._event_callbacks()

    def _event_callbacks(self):
        ''' Fire any new events '''
        for event in self.new_events:
            self.io_loop.add_callback(event[0], **event[1])
示例#42
0
 def render(self, *args, **kwargs):
     config = ConfigManager.instance()
     if config.recaptcha_enabled:
         return self.render_string('recaptcha/captcha.html')
     else:
         return self.render_string('recaptcha/disabled.html')
示例#43
0
 def initialize(self):
     """ Setup sessions, etc """
     self._session = None
     self._dbsession = dbsession
     self.config = ConfigManager.instance()
 def initialize(self):
     ''' Setup sessions, etc '''
     self.config = ConfigManager.instance()
示例#45
0
 def avatar(self):
     config = ConfigManager.instance()
     if self._avatar is not None:
         return self._avatar
     else:
         return "default_avatar.jpeg"
示例#46
0
 def delete_data(self):
     config = ConfigManager.instance()
     if os.path.exists(config.file_uploads_dir + self.uuid):
         os.unlink(config.file_uploads_dir + self.uuid)
示例#47
0
 def initialize(self):
     ''' Setup sessions, etc '''
     self._session = None
     self.config = ConfigManager.instance()
示例#48
0
 def render(self, *args, **kwargs):
     config = ConfigManager.instance()
     if config.recaptcha_enabled:
         return self.render_string('recaptcha/captcha.html')
     else:
         return self.render_string('recaptcha/disabled.html')
示例#49
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 sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from libs.ConfigManager import ConfigManager
from contextlib import contextmanager


### Setup the database session
_config = ConfigManager.instance()
engine = create_engine(_config.db_connection)
setattr(engine, 'echo', False)
_Session = sessionmaker(bind=engine)
StartSession = lambda: _Session(autoflush=True)

dbsession = StartSession()

@contextmanager
def cxt_dbsession():
    ''' Provide a transactional scope around a series of operations. '''
    session = StartSession()
    try:
        yield session
        session.commit()
    except:
示例#50
0
 def get_organizations_from_file():
     ''' Gets the JSON object containing an org list from the configured file '''
     config = ConfigManager.instance()
     with open(config.fb_organization_file, 'r') as f:
         return json.loads(f.read())