def make_me_admin(current): """Makes the current user into an admin.""" users.add(current, utils.get_current_username(current), "/", "Administrator") users.add(current, utils.get_current_username(current), "/", "Viewer") return {}
def clear_notifications(current): db = current.db db((db.notifications.user == utils.get_current_username(current)) & (db.notifications.read == True)).delete() return dict()
def my(current): """List all of the calling user's roles.""" db = current.db result = [] for row in db( db.permissions.user == utils.get_current_username(current)).select(): result.append(row.as_dict()) return dict(data=result)
def send_notifications(current, user, message_id, args): """Send a notification to the user.""" db = current.db db.notifications.insert( from_user=utils.get_current_username(current), user=user, message_id=message_id, args=args) return {}
def read_notifications(current): db = current.db result = [] for row in db( db.notifications.user == utils.get_current_username(current)).select(): result.append(row.as_dict()) if not row.read: row.update_record(read=True) return dict(data=result)
def log(current, type, **kwargs): kwargs["__type__"] = type user = kwargs["user"] = utils.get_current_username(current) # Access was made via a token. if current.request.token: kwargs["token_id"] = current.request.token["token_id"] current.db.audit.insert(timestamp=datetime.datetime.now(), message=serializer.unserialize(kwargs), user=user, type=type)
def request_approval(current, client_id, approver, role): """Request an approval from the specified user.""" # Notify the approver that a request is pending. users.send_notifications( current, approver, "APPROVAL_REQUEST", dict( client_id=client_id, user=utils.get_current_username(current), role=role)) audit.log(current, "ApprovalRequest", client_id=client_id, approver=approver, role=role) return {}
def mint_token(current, role, resource): # We can not mint tokens from delegated access! if current.request.token: raise PermissionDenied("token.mint", "/") db = current.db token_id = utils.new_token_id() db.tokens.insert(delegator=utils.get_current_username(current), token_id=token_id, role=role, resource=resource) return dict(token=token_id)
def InitializeMenu(): """Build the menu bar. Depending on permissions different options are visible. """ response.logo = A(IMG(_alt="Rekall Forensics", _class="logo", _src=URL('static', 'images', 'Rekall Logo.svg')), _class="navbar-brand web2py-menu-active link", _href=URL(c="default", f="index"), _id="logo") response.title = request.application.replace('_', ' ').title() response.subtitle = '' response.meta.author = "The Rekall Team" response.meta.description = "The Rekall Agent Server" response.meta.keywords = "Rekall, Forensics" if users.check_permission(current, "clients.search", "/"): response.menu.append( (T('Clients'), False, dict(_href="#", _id="client_lru"), [ (T('-'), False, None), ])) response.menu.append((T('Artifacts'), False, "#", [ (T('Manage Artifacts'), True, URL(c='artifacts', f='index')), (T('Precanned Flows'), True, URL(c='flows', f='list_canned')), ])) response.menu.append((T("Hunts"), True, URL(c="hunts", f="view"))) # User is administrator - show them the users menu.. if users.check_permission(current, "users.admin", "/"): response.menu.append((T('Users'), True, URL(c="users", f="manage"))) # Only app admins can access the raw DB. if users.is_user_app_admin(): response.menu.append((T('DB'), False, URL(c="appadmin", f="manage")), ) if users.check_permission(current, "audit.read", "/"): response.menu.append((T('Audit'), True, URL(c="audit", f="search"))) response.menu.append((T('Api'), True, URL(c="default", f="api"))) response.right_menu = [(utils.get_current_username(current), False, "#", [ (T('Logout'), False, URL('default', 'logout'), []), ])] if config.GetConfig(current).demo: response.right_menu.append(("Demo", True, URL(c="default", f="demo")))
def propose_from_flows(current, flow_ids, labels, approvers, name=None): """Launch a hunt from the flows on these labels.""" hunt_id = utils.new_hunt_id() now = time.time() also_upload_files = False result = agent.Flow.from_keywords( name=name or hunt_id, flow_id=hunt_id, created_time=now, creator=utils.get_current_username(current), ticket=dict( location=dict( __type__="HTTPLocation", base=utils.route_api('/control/hunt_ticket'), path_prefix=hunt_id, )), ) db = current.db seen = set() for flow_id in flow_ids: row = db(db.flows.flow_id == flow_id).select().first() if row: for action in row.flow.actions: if action.rekall_session.get("also_upload_files"): also_upload_files = True if isinstance(action, actions.PluginAction): action = actions.PluginAction.from_keywords( plugin=action.plugin, rekall_session=action.rekall_session, collection=dict( __type__="JSONCollection", location=dict( __type__="BlobUploader", base=html.URL( c="api", f="control", args=['upload'], host=True), path_template=( "collection/%s/{part}" % hunt_id), )), args=action.args) # Dedupe identical canned actions. key = action.to_json() if key in seen: continue seen.add(key) result.actions.append(action) if also_upload_files: result.file_upload = dict( __type__="FileUploadLocation", flow_id=hunt_id, base=html.URL(c="api", f='control/file_upload', host=True)) # Add the hunt to the hunts table. db.hunts.insert( hunt_id=hunt_id, creator=result.creator, flow=result, labels=labels, state="Proposed", timestamp=now) for approver in approvers: users.send_notifications( current, approver, "HUNT_APPROVAL_REQUEST", dict( hunt_id=hunt_id, user=utils.get_current_username(current))) audit.log(current, "HuntProposal", hunt_id=hunt_id) return {}
def count_notifications(current): user = utils.get_current_username(current) db = current.db return db((db.notifications.user == user) & (db.notifications.read == False)).count()
def launch_canned_flows(current, client_id, name): db = current.db row = db(db.canned_flows.name == name).select().first() if not row: raise ValueError("There is no canned flow with name '%s'" % name) also_upload_files = False flow_id = utils.new_flow_id() for action in row.flow.actions: if action.rekall_session.get("also_upload_files"): also_upload_files = True action.collection = dict(__type__="JSONCollection", location=dict( __type__="BlobUploader", base=html.URL(c="api", f="control", args=['upload'], host=True), path_template=("collection/%s/{part}" % flow_id), )) flow = agent.Flow.from_keywords( name=name, flow_id=flow_id, created_time=time.time(), ticket=dict(location=dict( __type__="HTTPLocation", base=utils.route_api('/control/ticket'), path_prefix=flow_id, )), actions=row.flow.actions, ) if also_upload_files: flow.file_upload = dict(__type__="FileUploadLocation", flow_id=flow_id, base=html.URL(c="api", f='control/file_upload', host=True)) db.flows.insert( flow_id=flow_id, client_id=client_id, status=agent.FlowStatus.from_keywords(timestamp=time.time(), client_id=client_id, flow_id=flow_id, status="Pending"), creator=utils.get_current_username(current), flow=flow, timestamp=flow.created_time.timestamp, ) firebase.notify_client(client_id) audit.log(current, "FlowLaunchCanned", flow_id=flow_id, canned_flow=name, client_id=client_id) return {}
def launch_plugin_flow(current, client_id, rekall_session, plugin, plugin_arg): """Launch the flow on the client.""" db = current.db flow_id = utils.new_flow_id() spec = plugins.RekallAPI(current).get(plugin) if not spec: raise ValueError("Unknown plugin") # Validate both plugin args and session args. validate_plugin_args(plugin_arg, spec) validate_plugin_args(rekall_session, plugins.SessionAPI(current)) flow = agent.Flow.from_keywords( flow_id=flow_id, created_time=time.time(), ticket=dict(location=dict( __type__="HTTPLocation", base=utils.route_api('/control/ticket'), path_prefix=flow_id, )), actions=[ dict(__type__="PluginAction", plugin=plugin, args=plugin_arg, rekall_session=rekall_session, collection=dict(__type__="JSONCollection", location=dict( __type__="BlobUploader", base=html.URL(c="api", f="control", args=['upload'], host=True), path_template=("collection/%s/{part}" % flow_id), ))) ]) if rekall_session.get("also_upload_files"): flow.file_upload = dict(__type__="FileUploadLocation", flow_id=flow_id, base=html.URL(c="api", f='control/file_upload', host=True)) db.flows.insert( flow_id=flow_id, client_id=client_id, status=agent.FlowStatus.from_keywords(timestamp=time.time(), client_id=client_id, flow_id=flow_id, status="Pending"), creator=utils.get_current_username(current), flow=flow, timestamp=flow.created_time.timestamp, ) firebase.notify_client(client_id) audit.log(current, "FlowLaunchPlugin", flow_id=flow_id, plugin=plugin, client_id=client_id) return {}