def _AddWorker(self): worker_name = self.name + "-%d" % random.UInt32() worker = _WorkerThread(self._queue, self, worker_name) worker.start() self._workers[worker.name] = worker self._workers_ro_copy = self._workers.copy()
def __init__(self, initializer=None, base="aff4:/flows", queue=DEFAULT_FLOW_QUEUE, flow_name=None): """Constructor. Args: initializer: A string or another RDFURN. base: The base namespace this session id lives in. queue: The queue to use. flow_name: The name of this flow or its random id. Raises: InitializeError: The given URN cannot be converted to a SessionID. """ if initializer is None: # This SessionID is being constructed from scratch. if flow_name is None: flow_name = random.UInt32() if isinstance(flow_name, int): initializer = RDFURN(base).Add("%s:%X" % (queue.Basename(), flow_name)) else: initializer = RDFURN(base).Add("%s:%s" % (queue.Basename(), flow_name)) else: if isinstance(initializer, RDFURN): try: self.ValidateID(initializer.Basename()) except ValueError as e: raise InitializeError("Invalid URN for SessionID: %s, %s" % (initializer, e)) super(SessionID, self).__init__(initializer=initializer)
def __init__(self, initializer=None, age=None, **kwargs): super(AuditEvent, self).__init__(initializer=initializer, age=age, **kwargs) if not self.id: self.id = random.UInt32() if not self.timestamp: self.timestamp = rdfvalue.RDFDatetime.Now()
def Request(self): """Create the Approval object and notify the Approval Granter.""" approval_id = "approval:%X" % random.UInt32() approval_urn = self.BuildApprovalUrn(approval_id) email_msg_id = email.utils.make_msgid() with aff4.FACTORY.Create(approval_urn, self.approval_type, mode="w", token=self.token) as approval_request: approval_request.Set( approval_request.Schema.SUBJECT(self.subject_urn)) approval_request.Set( approval_request.Schema.REQUESTOR(self.token.username)) approval_request.Set(approval_request.Schema.REASON(self.reason)) approval_request.Set( approval_request.Schema.EMAIL_MSG_ID(email_msg_id)) cc_addresses = (self.email_cc_address, config.CONFIG.Get("Email.approval_cc_address")) email_cc = ",".join(filter(None, cc_addresses)) # When we reply with the approval we want to cc all the people to whom the # original approval was sent, to avoid people approving stuff that was # already approved. if email_cc: reply_cc = ",".join((self.approver, email_cc)) else: reply_cc = self.approver approval_request.Set(approval_request.Schema.EMAIL_CC(reply_cc)) approval_request.Set( approval_request.Schema.NOTIFIED_USERS(self.approver)) # We add ourselves as an approver as well (The requirement is that we have # 2 approvers, so the requester is automatically an approver). approval_request.AddAttribute( approval_request.Schema.APPROVER(self.token.username)) approval_link_urns = self.BuildApprovalSymlinksUrns(approval_id) for link_urn in approval_link_urns: with aff4.FACTORY.Create(link_urn, aff4.AFF4Symlink, mode="w", token=self.token) as link: link.Set(link.Schema.SYMLINK_TARGET(approval_urn)) return approval_urn
def HandleWellKnownFlows(self, messages): """Hands off messages to well known flows.""" msgs_by_wkf = {} result = [] for msg in messages: # Regular message - queue it. if msg.response_id != 0: result.append(msg) continue # Well known flows: flow_name = msg.session_id.FlowName() if flow_name in self.well_known_flows: # This message should be processed directly on the front end. msgs_by_wkf.setdefault(flow_name, []).append(msg) # TODO(user): Deprecate in favor of 'well_known_flow_requests' # metric. stats_collector_instance.Get().IncrementCounter( "grr_well_known_flow_requests") stats_collector_instance.Get().IncrementCounter( "well_known_flow_requests", fields=[str(msg.session_id)]) else: # Message should be queued to be processed in the backend. # Well known flows have a response_id==0, but if we queue up the state # as that it will overwrite some other message that is queued. So we # change it to a random number here. msg.response_id = random.UInt32() # Queue the message in the data store. result.append(msg) for flow_name, msg_list in iteritems(msgs_by_wkf): wkf = self.well_known_flows[flow_name] wkf.ProcessMessages(msg_list) return result
def SetPassword(self, password, salt=None): if salt is None: salt = "%08x" % random.UInt32() self._value = self._CalculateHash(password, salt) return self
def testSpecific(self): self.assertEqual(random.UInt32(), 0xDEADBEEF) self.assertEqual(random.UInt32(), 0xBADDCAFE)
def testMax(self, urandom): del urandom # Unused. for _ in range(10000): self.assertEqual(random.UInt32(), 2**32 - 1)
def ReceiveMessages(self, client_id: str, messages: Iterable[rdf_flows.GrrMessage]): """Receives and processes the messages. For each message we update the request object, and place the response in that request's queue. If the request is complete, we send a message to the worker. Args: client_id: The client which sent the messages. messages: A list of GrrMessage RDFValues. """ now = time.time() unprocessed_msgs = [] worker_message_handler_requests = [] frontend_message_handler_requests = [] dropped_count = 0 msgs_by_session_id = collection.Group(messages, lambda m: m.session_id) for session_id, msgs in msgs_by_session_id.items(): for msg in msgs: if (msg.auth_state != msg.AuthorizationState.AUTHENTICATED and msg.session_id != self.unauth_allowed_session_id): dropped_count += 1 continue session_id_str = str(session_id) if session_id_str in message_handlers.session_id_map: request = rdf_objects.MessageHandlerRequest( client_id=msg.source.Basename(), handler_name=message_handlers. session_id_map[session_id], request_id=msg.response_id or random.UInt32(), request=msg.payload) if request.handler_name in self._SHORTCUT_HANDLERS: frontend_message_handler_requests.append(request) else: worker_message_handler_requests.append(request) elif session_id_str in self.legacy_well_known_session_ids: logging.debug( "Dropping message for legacy well known session id %s", session_id) else: unprocessed_msgs.append(msg) if dropped_count: logging.info("Dropped %d unauthenticated messages for %s", dropped_count, client_id) if unprocessed_msgs: flow_responses = [] for message in unprocessed_msgs: try: flow_responses.append( rdf_flow_objects.FlowResponseForLegacyResponse( message)) except ValueError as e: logging.warning( "Failed to parse legacy FlowResponse:\n%s\n%s", e, message) data_store.REL_DB.WriteFlowResponses(flow_responses) for msg in unprocessed_msgs: if msg.type == rdf_flows.GrrMessage.Type.STATUS: stat = rdf_flows.GrrStatus(msg.payload) if stat.status == rdf_flows.GrrStatus.ReturnedStatus.CLIENT_KILLED: # A client crashed while performing an action, fire an event. crash_details = rdf_client.ClientCrash( client_id=client_id, session_id=msg.session_id, backtrace=stat.backtrace, crash_message=stat.error_message, nanny_status=stat.nanny_status, timestamp=rdfvalue.RDFDatetime.Now()) events.Events.PublishEvent("ClientCrash", crash_details, token=self.token) if worker_message_handler_requests: data_store.REL_DB.WriteMessageHandlerRequests( worker_message_handler_requests) if frontend_message_handler_requests: worker_lib.ProcessMessageHandlerRequests( frontend_message_handler_requests) logging.debug("Received %s messages from %s in %s sec", len(messages), client_id, time.time() - now)
def GenerateRunId(self): self.run_id = "%08X" % random.UInt32() return self.run_id