コード例 #1
0
ファイル: user.py プロジェクト: costaafm/grr
 def BuildSubjectId(self):
     return utils.SmartStr(self.cron_job_id)
コード例 #2
0
 def Seek(self, offset, whence=0):
     if not self.fd:
         self.fd = io.BytesIO(utils.SmartStr(self.value))
     return self.fd.seek(offset, whence)
コード例 #3
0
    def CreateClientObject(self, vfs_fixture):
        """Make a new client object."""

        # First remove the old fixture just in case its still there.
        aff4.FACTORY.Delete(self.client_id, token=self.token)

        # Create the fixture at a fixed time.
        with test_lib.FakeTime(self.age):
            for path, (aff4_type, attributes) in vfs_fixture:
                path %= self.args

                aff4_object = aff4.FACTORY.Create(self.client_id.Add(path),
                                                  aff4_type,
                                                  mode="rw",
                                                  token=self.token)

                if data_store.RelationalDBWriteEnabled():
                    data_store.REL_DB.WriteClientMetadata(
                        self.client_id.Basename(), fleetspeak_enabled=False)

                    components = [
                        component for component in path.split("/") if component
                    ]
                    if components[0:2] == ["fs", "os"]:
                        path_info = rdf_objects.PathInfo()
                        path_info.path_type = rdf_objects.PathInfo.PathType.OS
                        path_info.components = components[2:]
                        if aff4_type in [
                                aff4_grr.VFSFile, aff4_grr.VFSMemoryFile
                        ]:
                            path_info.directory = False
                        elif aff4_type == aff4_standard.VFSDirectory:
                            path_info.directory = True
                        else:
                            raise ValueError("Incorrect AFF4 type: %s" %
                                             aff4_type)
                        data_store.REL_DB.WritePathInfos(
                            client_id=self.client_id.Basename(),
                            path_infos=[path_info])

                for attribute_name, value in iteritems(attributes):
                    attribute = aff4.Attribute.PREDICATES[attribute_name]
                    if isinstance(value, (str, unicode)):
                        # Interpolate the value
                        value %= self.args

                    # Is this supposed to be an RDFValue array?
                    if aff4.issubclass(attribute.attribute_type,
                                       rdf_protodict.RDFValueArray):
                        rdfvalue_object = attribute()
                        for item in value:
                            new_object = rdfvalue_object.rdf_type.FromTextFormat(
                                utils.SmartStr(item))
                            rdfvalue_object.Append(new_object)

                    # It is a text serialized protobuf.
                    elif aff4.issubclass(attribute.attribute_type,
                                         rdf_structs.RDFProtoStruct):
                        # Use the alternate constructor - we always write protobufs in
                        # textual form:
                        rdfvalue_object = attribute.attribute_type.FromTextFormat(
                            utils.SmartStr(value))

                    elif aff4.issubclass(attribute.attribute_type,
                                         rdfvalue.RDFInteger):
                        rdfvalue_object = attribute(int(value))
                    else:
                        rdfvalue_object = attribute(value)

                    # If we don't already have a pathspec, try and get one from the stat.
                    if aff4_object.Get(aff4_object.Schema.PATHSPEC) is None:
                        # If the attribute was a stat, it has a pathspec nested in it.
                        # We should add that pathspec as an attribute.
                        if attribute.attribute_type == rdf_client_fs.StatEntry:
                            stat_object = attribute.attribute_type.FromTextFormat(
                                utils.SmartStr(value))
                            if stat_object.pathspec:
                                pathspec_attribute = aff4.Attribute(
                                    "aff4:pathspec", rdf_paths.PathSpec,
                                    "The pathspec used to retrieve "
                                    "this object from the client.", "pathspec")
                                aff4_object.AddAttribute(
                                    pathspec_attribute, stat_object.pathspec)

                    if attribute in ["aff4:content", "aff4:content"]:
                        # For AFF4MemoryStreams we need to call Write() instead of
                        # directly setting the contents..
                        aff4_object.Write(rdfvalue_object.AsBytes())
                    else:
                        aff4_object.AddAttribute(attribute, rdfvalue_object)

                    if (isinstance(rdfvalue_object, rdf_client_fs.StatEntry)
                            and rdfvalue_object.pathspec.pathtype != "UNSET"):
                        if data_store.RelationalDBWriteEnabled():
                            client_id = self.client_id.Basename()
                            path_info = rdf_objects.PathInfo.FromStatEntry(
                                rdfvalue_object)
                            data_store.REL_DB.WritePathInfos(
                                client_id, [path_info])

                # Populate the KB from the client attributes.
                if aff4_type == aff4_grr.VFSGRRClient:
                    kb = rdf_client.KnowledgeBase()
                    artifact.SetCoreGRRKnowledgeBaseValues(kb, aff4_object)
                    aff4_object.Set(aff4_object.Schema.KNOWLEDGE_BASE, kb)

                # Make sure we do not actually close the object here - we only want to
                # sync back its attributes, not run any finalization code.
                aff4_object.Flush()
                if aff4_type == aff4_grr.VFSGRRClient:
                    index = client_index.CreateClientIndex(token=self.token)
                    index.AddClient(aff4_object)
コード例 #4
0
 def SerializeToString(self):
     return utils.SmartStr(self._value)
コード例 #5
0
 def __str__(self):
     return utils.SmartStr("aff4:%s" % self._string_urn)
コード例 #6
0
ファイル: client.py プロジェクト: slad99/grr
 def __str__(self):
     return utils.SmartStr(self.__unicode__())
コード例 #7
0
 def __str__(self):
     return utils.SmartStr(self._value)
コード例 #8
0
    def GetApprovalForObject(object_urn, token=None, username=""):
        """Looks for approvals for an object and returns available valid tokens.

    Args:
      object_urn: Urn of the object we want access to.

      token: The token to use to lookup the ACLs.

      username: The user to get the approval for, if "" we get it from the
        token.

    Returns:
      A token for access to the object on success, otherwise raises.

    Raises:
      UnauthorizedAccess: If there are no valid approvals available.

    """
        if token is None:
            raise access_control.UnauthorizedAccess(
                "No token given, cannot authenticate.")

        if not username:
            username = token.username

        approvals_root_urn = aff4.ROOT_URN.Add("ACL").Add(
            object_urn.Path()).Add(username)

        children_urns = list(aff4.FACTORY.ListChildren(approvals_root_urn))
        if not children_urns:
            raise access_control.UnauthorizedAccess(
                "No approval found for user %s" % utils.SmartStr(username),
                subject=object_urn)

        last_error = None
        approvals = aff4.FACTORY.MultiOpen(children_urns,
                                           mode="r",
                                           aff4_type=Approval,
                                           age=aff4.ALL_TIMES,
                                           token=token)
        for approval in approvals:
            try:
                test_token = access_control.ACLToken(
                    username=username,
                    reason=approval.Get(approval.Schema.REASON))
                approval.CheckAccess(test_token)

                return test_token
            except access_control.UnauthorizedAccess as e:
                last_error = e

        if last_error:
            # We tried all possible approvals, but got no usable results.
            raise access_control.UnauthorizedAccess(last_error,
                                                    subject=object_urn)
        else:
            # If last error is None, means that none of the URNs in children_urns
            # could be opened. This shouldn't really happen ever, but we have
            # to make sure to provide a meaningful error message.
            raise access_control.UnauthorizedAccess(
                "Couldn't open any of %d approvals "
                "for user %s" % (len(children_urns), utils.SmartStr(username)),
                subject=object_urn)
コード例 #9
0
    def ProcessMessages(self, msgs=None, token=None):
        """Processes this event."""
        nanny_msg = ""

        for crash_details in msgs:
            client_id = crash_details.client_id

            # The session id of the flow that crashed.
            session_id = crash_details.session_id

            flow_obj = aff4.FACTORY.Open(session_id, token=token)

            # Log.
            logging.info("Client crash reported, client %s.", client_id)

            # Export.
            stats.STATS.IncrementCounter("grr_client_crashes")

            # Write crash data to AFF4.
            if data_store.RelationalDBReadEnabled():
                client = data_store.REL_DB.ReadClientSnapshot(
                    client_id.Basename())
                client_info = client.startup_info.client_info
            else:
                client = aff4.FACTORY.Open(client_id, token=token)
                client_info = client.Get(client.Schema.CLIENT_INFO)

            crash_details.client_info = client_info
            crash_details.crash_type = "Client Crash"

            WriteAllCrashDetails(client_id,
                                 crash_details,
                                 flow_session_id=session_id,
                                 token=token)

            # Also send email.
            to_send = []

            try:
                hunt_session_id = ExtractHuntId(session_id)
                if hunt_session_id and hunt_session_id != session_id:
                    hunt_obj = aff4.FACTORY.Open(
                        hunt_session_id,
                        aff4_type=implementation.GRRHunt,
                        token=token)
                    email = hunt_obj.runner_args.crash_alert_email
                    if email:
                        to_send.append(email)
            except aff4.InstantiationError:
                logging.error("Failed to open hunt %s.", hunt_session_id)

            email = config.CONFIG["Monitoring.alert_email"]
            if email:
                to_send.append(email)

            for email_address in to_send:
                if crash_details.nanny_status:
                    nanny_msg = "Nanny status: %s" % crash_details.nanny_status

                client = aff4.FACTORY.Open(client_id, token=token)
                hostname = client.Get(client.Schema.HOSTNAME)
                url = "/clients/%s" % client_id.Basename()

                body = self.__class__.mail_template.render(
                    client_id=client_id,
                    admin_ui=config.CONFIG["AdminUI.url"],
                    hostname=utils.SmartUnicode(hostname),
                    context=utils.SmartUnicode(flow_obj.context),
                    state=utils.SmartUnicode(flow_obj.state),
                    args=utils.SmartUnicode(flow_obj.args),
                    runner_args=utils.SmartUnicode(flow_obj.runner_args),
                    urn=url,
                    nanny_msg=utils.SmartUnicode(nanny_msg),
                    signature=config.CONFIG["Email.signature"])
                email_alerts.EMAIL_ALERTER.SendEmail(
                    email_address,
                    "GRR server",
                    "Client %s reported a crash." % client_id,
                    utils.SmartStr(body),
                    is_html=True)

            if nanny_msg:
                msg = "Client crashed, " + nanny_msg
            else:
                msg = "Client crashed."

            # Now terminate the flow.
            flow.GRRFlow.TerminateFlow(session_id,
                                       reason=msg,
                                       token=token,
                                       force=True)
コード例 #10
0
ファイル: user.py プロジェクト: costaafm/grr
 def subject_url_path(self):
     return "/crons/%s" % utils.SmartStr(self.subject.cron_job_id)
コード例 #11
0
ファイル: user.py プロジェクト: costaafm/grr
 def BuildSubjectId(self):
     return utils.SmartStr(self.hunt_id)
コード例 #12
0
ファイル: user.py プロジェクト: costaafm/grr
 def review_url_path(self):
     return "/".join([
         "users", self.requestor, "approvals", "cron-job",
         utils.SmartStr(self.subject.cron_job_id),
         utils.SmartStr(self.id)
     ])
コード例 #13
0
ファイル: user.py プロジェクト: costaafm/grr
 def subject_url_path(self):
     return "/hunts/%s" % utils.SmartStr(self.subject.hunt_id)
コード例 #14
0
ファイル: user.py プロジェクト: costaafm/grr
 def review_url_path(self):
     return "/".join([
         "users", self.requestor, "approvals", "hunt",
         utils.SmartStr(self.subject.hunt_id),
         utils.SmartStr(self.id)
     ])
コード例 #15
0
ファイル: client.py プロジェクト: esmat777/grr
  def InitFromAff4Object(self, client_obj, include_metadata=True):
    # TODO(amoser): Deprecate all urns.
    self.urn = client_obj.urn

    self.client_id = client_obj.urn.Basename()

    self.agent_info = client_obj.Get(client_obj.Schema.CLIENT_INFO)
    self.hardware_info = client_obj.Get(client_obj.Schema.HARDWARE_INFO)
    self.os_info = rdf_client.Uname(
        system=client_obj.Get(client_obj.Schema.SYSTEM),
        release=client_obj.Get(client_obj.Schema.OS_RELEASE),
        # TODO(user): Check if ProtoString.Validate should be fixed
        # to do an isinstance() check on a value. Is simple type
        # equality check used there for performance reasons?
        version=utils.SmartStr(
            client_obj.Get(client_obj.Schema.OS_VERSION, "")),
        kernel=client_obj.Get(client_obj.Schema.KERNEL),
        machine=client_obj.Get(client_obj.Schema.ARCH),
        fqdn=(client_obj.Get(client_obj.Schema.FQDN) or
              client_obj.Get(client_obj.Schema.HOSTNAME)),
        install_date=client_obj.Get(client_obj.Schema.INSTALL_DATE))
    self.knowledge_base = client_obj.Get(client_obj.Schema.KNOWLEDGE_BASE)
    self.memory_size = client_obj.Get(client_obj.Schema.MEMORY_SIZE)

    self.first_seen_at = client_obj.Get(client_obj.Schema.FIRST_SEEN)

    if include_metadata:
      ping = client_obj.Get(client_obj.Schema.PING)
      if ping:
        self.last_seen_at = ping

      booted = client_obj.Get(client_obj.Schema.LAST_BOOT_TIME)
      if booted:
        self.last_booted_at = booted

      clock = client_obj.Get(client_obj.Schema.CLOCK)
      if clock:
        self.last_clock = clock

      last_crash = client_obj.Get(client_obj.Schema.LAST_CRASH)
      if last_crash is not None:
        self.last_crash_at = last_crash.timestamp

      self.fleetspeak_enabled = bool(
          client_obj.Get(client_obj.Schema.FLEETSPEAK_ENABLED))

    self.labels = [
        rdf_objects.ClientLabel(name=l.name, owner=l.owner)
        for l in client_obj.GetLabels()
    ]
    self.interfaces = client_obj.Get(client_obj.Schema.INTERFACES)
    kb = client_obj.Get(client_obj.Schema.KNOWLEDGE_BASE)
    if kb and kb.users:
      self.users = sorted(kb.users, key=lambda user: user.username)
    self.volumes = client_obj.Get(client_obj.Schema.VOLUMES)

    type_obj = client_obj.Get(client_obj.Schema.TYPE)
    if type_obj:
      # Without self.Set self.age would reference "age" attribute instead of a
      # protobuf field.
      self.Set("age", type_obj.age)

    self.cloud_instance = client_obj.Get(client_obj.Schema.CLOUD_INSTANCE)
    return self
コード例 #16
0
    def Control(self):
        """Handle POSTS."""
        if not master.MASTER_WATCHER.IsMaster():
            # We shouldn't be getting requests from the client unless we
            # are the active instance.
            stats_collector_instance.Get().IncrementCounter(
                "frontend_inactive_request_count", fields=["http"])
            logging.info("Request sent to inactive frontend from %s",
                         self.client_address[0])

        # Get the api version
        try:
            api_version = int(cgi.parse_qs(self.path.split("?")[1])["api"][0])
        except (ValueError, KeyError, IndexError):
            # The oldest api version we support if not specified.
            api_version = 3

        try:
            content_length = self.headers.getheader("content-length")
            if not content_length:
                raise IOError("No content-length header provided.")

            length = int(content_length)

            request_comms = rdf_flows.ClientCommunication.FromSerializedString(
                self._GetPOSTData(length))

            # If the client did not supply the version in the protobuf we use the get
            # parameter.
            if not request_comms.api_version:
                request_comms.api_version = api_version

            # Reply using the same version we were requested with.
            responses_comms = rdf_flows.ClientCommunication(
                api_version=request_comms.api_version)

            source_ip = ipaddr.IPAddress(self.client_address[0])

            if source_ip.version == 6:
                source_ip = source_ip.ipv4_mapped or source_ip

            request_comms.orig_request = rdf_flows.HttpRequest(
                timestamp=rdfvalue.RDFDatetime.Now().AsMicrosecondsSinceEpoch(
                ),
                raw_headers=utils.SmartStr(self.headers),
                source_ip=utils.SmartStr(source_ip))

            source, nr_messages = self.server.frontend.HandleMessageBundles(
                request_comms, responses_comms)

            server_logging.LOGGER.LogHttpFrontendAccess(
                request_comms.orig_request,
                source=source,
                message_count=nr_messages)

            self.Send(responses_comms.SerializeToString())

        except communicator.UnknownClientCert:
            # "406 Not Acceptable: The server can only generate a response that is not
            # accepted by the client". This is because we can not encrypt for the
            # client appropriately.
            self.Send("Enrollment required", status=406)
コード例 #17
0
ファイル: client.py プロジェクト: esmat777/grr
 def ObjectReference(self):
   return rdf_objects.ObjectReference(
       reference_type=rdf_objects.ObjectReference.Type.CLIENT,
       client=rdf_objects.ClientReference(
           client_id=utils.SmartStr(self.client_id)))
コード例 #18
0
 def ToString(self, value):
     return utils.SmartStr(value)
コード例 #19
0
 def ParseFromString(self, initializer):
     # Old clients sometimes send bare well known flow ids.
     if not utils.SmartStr(initializer).startswith("aff4"):
         initializer = "aff4:/flows/" + initializer
     super(FlowSessionID, self).ParseFromString(initializer)
コード例 #20
0
ファイル: rdfvalue.py プロジェクト: cdstelly/grr
 def __eq__(self, other):
     return (self._value == utils.SmartStr(other)
             or binascii.hexlify(self._value) == other)
コード例 #21
0
 def ParseFromString(self, string):
     # This handles the cases when we're initialized from Unicode strings.
     self._value = utils.SmartStr(string)
コード例 #22
0
ファイル: build.py プロジェクト: skirankumar/grr
    def BuildWithPyInstaller(self):
        """Use pyinstaller to build a client package."""
        self.CleanDirectory(
            config.CONFIG.Get("PyInstaller.distpath", context=self.context))

        logging.info("Copying pyinstaller support files")
        self.spec_file = os.path.join(self.build_dir, "grr.spec")

        with open(self.spec_file, "wb") as fd:
            fd.write(
                config.CONFIG.Get("PyInstaller.spec", context=self.context))

        with open(os.path.join(self.build_dir, "version.txt"), "wb") as fd:
            fd.write(
                config.CONFIG.Get("PyInstaller.version", context=self.context))

        shutil.copy(src=config.CONFIG.Get("PyInstaller.icon_path",
                                          context=self.context),
                    dst=os.path.join(self.build_dir, u"grr.ico"))

        # We expect the onedir output at this location.
        self.output_dir = os.path.join(
            config.CONFIG.Get("PyInstaller.distpath", context=self.context),
            "grr-client")

        # Pyinstaller doesn't handle unicode strings.
        args = [
            "--distpath",
            str(config.CONFIG.Get("PyInstaller.distpath",
                                  context=self.context)), "--workpath",
            str(
                config.CONFIG.Get("PyInstaller.workpath_dir",
                                  context=self.context)),
            str(self.spec_file)
        ]
        logging.info("Running pyinstaller: %s", args)
        PyInstallerMain.run(pyi_args=[utils.SmartStr(x) for x in args])

        # Clear out some crud that pyinstaller includes.
        for path in ["tcl", "tk", "pytz"]:
            dir_path = os.path.join(self.output_dir, path)
            try:
                shutil.rmtree(dir_path)
            except OSError:
                logging.error("Unable to remove directory: %s", dir_path)

            try:
                os.mkdir(dir_path)
            except OSError:
                logging.error("Unable to create directory: %s", dir_path)

            file_path = os.path.join(dir_path, path)
            try:
                # Create an empty file so the directories get put in the installers.
                with open(file_path, "wb"):
                    pass
            except IOError:
                logging.error("Unable to create file: %s", file_path)

        version_ini = version.VersionPath()
        shutil.copy(version_ini, os.path.join(self.output_dir, "version.ini"))

        with open(os.path.join(self.output_dir, "build.yaml"), "wb") as fd:
            self.WriteBuildYaml(fd)
コード例 #23
0
 def __eq__(self, other):
     return (self._value == utils.SmartStr(other)
             or self._value.encode("hex") == other)
コード例 #24
0
  def __init__(self, base_fd, pathspec=None, progress_callback=None):
    """Use TSK to read the pathspec.

    Args:
      base_fd: The file like object we read this component from.
      pathspec: An optional pathspec to open directly.
      progress_callback: A callback to indicate that the open call is still
        working but needs more time.

    Raises:
      IOError: If the file can not be opened.
    """
    super(TSKFile, self).__init__(
        base_fd, pathspec=pathspec, progress_callback=progress_callback)
    if self.base_fd is None:
      raise IOError("TSK driver must have a file base.")

    # If our base is another tsk driver - borrow the reference to the raw
    # device, and replace the last pathspec component with this one after
    # extending its path.
    elif isinstance(base_fd, TSKFile) and self.base_fd.IsDirectory():
      self.tsk_raw_device = self.base_fd.tsk_raw_device
      last_path = utils.JoinPath(self.pathspec.last.path, pathspec.path)

      # Replace the last component with this one.
      self.pathspec.Pop(-1)
      self.pathspec.Append(pathspec)
      self.pathspec.last.path = last_path

    # Use the base fd as a base to parse the filesystem only if its file like.
    elif not self.base_fd.IsDirectory():
      self.tsk_raw_device = self.base_fd
      self.pathspec.Append(pathspec)
    else:
      # If we get here we have a directory from a non sleuthkit driver - dont
      # know what to do with it.
      raise IOError("Unable to parse base using Sleuthkit.")

    # If we are successful in opening this path below the path casing is
    # correct.
    self.pathspec.last.path_options = rdf_paths.PathSpec.Options.CASE_LITERAL

    fd_hash = self.tsk_raw_device.pathspec.SerializeToString()

    # Cache the filesystem using the path of the raw device
    try:
      self.filesystem = vfs.DEVICE_CACHE.Get(fd_hash)
      self.fs = self.filesystem.fs
    except KeyError:
      self.img = MyImgInfo(
          fd=self.tsk_raw_device, progress_callback=progress_callback)

      self.fs = pytsk3.FS_Info(self.img, 0)
      self.filesystem = CachedFilesystem(self.fs, self.img)

      vfs.DEVICE_CACHE.Put(fd_hash, self.filesystem)

    # We prefer to open the file based on the inode because that is more
    # efficient.
    if pathspec.HasField("inode"):
      self.fd = self.fs.open_meta(pathspec.inode)
      self.tsk_attribute = self.GetAttribute(pathspec.ntfs_type,
                                             pathspec.ntfs_id)
      if self.tsk_attribute:
        self.size = self.tsk_attribute.info.size
      else:
        self.size = self.fd.info.meta.size

    else:
      # Does the filename exist in the image?
      self.fd = self.fs.open(utils.SmartStr(self.pathspec.last.path))
      self.size = self.fd.info.meta.size
      self.pathspec.last.inode = self.fd.info.meta.addr
コード例 #25
0
    def Read(self, length):
        if not self.fd:
            self.fd = io.BytesIO(utils.SmartStr(self.value))

        return self.fd.read(length)
コード例 #26
0
    def HandleRequest(self, request):
        """Handles given HTTP request."""
        impersonated_username = config.CONFIG["AdminUI.debug_impersonate_user"]
        if impersonated_username:
            logging.info("Overriding user as %s", impersonated_username)
            request.user = config.CONFIG["AdminUI.debug_impersonate_user"]

        if not aff4_users.GRRUser.IsValidUsername(request.user):
            return self._BuildResponse(
                403, dict(message="Invalid username: %s" % request.user))

        try:
            router, method_metadata, args = self._router_matcher.MatchRouter(
                request)
        except access_control.UnauthorizedAccess as e:
            logging.exception("Access denied to %s (%s): %s", request.path,
                              request.method, e)

            additional_headers = {
                "X-GRR-Unauthorized-Access-Reason":
                utils.SmartStr(e.message).replace("\n", ""),
                "X-GRR-Unauthorized-Access-Subject":
                utils.SmartStr(e.subject)
            }
            return self._BuildResponse(
                403,
                dict(message="Access denied by ACL: %s" %
                     utils.SmartStr(e.message),
                     subject=utils.SmartStr(e.subject)),
                headers=additional_headers)

        except ApiCallRouterNotFoundError as e:
            return self._BuildResponse(404, dict(message=e.message))
        except werkzeug_exceptions.MethodNotAllowed as e:
            return self._BuildResponse(405, dict(message=e.message))
        except Error as e:
            logging.exception("Can't match URL to router/method: %s", e)

            return self._BuildResponse(
                500, dict(message=str(e), traceBack=traceback.format_exc()))

        request.method_metadata = method_metadata
        request.parsed_args = args

        # SetUID() is called here so that ACL checks done by the router do not
        # clash with datastore ACL checks.
        # TODO(user): increase token expiry time.
        token = self.BuildToken(request, 60).SetUID()

        # AFF4 edge case: if a user is issuing a request, before they are created
        # using CreateGRRUser (e.g. in E2E tests or with single sign-on),
        # AFF4's ReadGRRUsers will NEVER contain the user, because the creation
        # done in the following lines does not add the user to the /users/
        # collection. Furthermore, subsequent CreateGrrUserHandler calls fail,
        # because the user technically already exists.

        # We send a blind-write request to ensure that the user object is created
        # for a user specified by the username.
        user_urn = rdfvalue.RDFURN("aff4:/users/").Add(request.user)
        # We can't use conventional AFF4 interface, since aff4.FACTORY.Create will
        # create a new version of the object for every call.
        with data_store.DB.GetMutationPool() as pool:
            pool.MultiSet(user_urn, {
                aff4_users.GRRUser.SchemaCls.TYPE:
                [aff4_users.GRRUser.__name__],
                aff4_users.GRRUser.SchemaCls.LAST:
                [rdfvalue.RDFDatetime.Now().SerializeToDataStore()]
            },
                          replace=True)

        if data_store.RelationalDBWriteEnabled():
            data_store.REL_DB.WriteGRRUser(request.user)

        handler = None
        try:
            # ACL checks are done here by the router. If this method succeeds (i.e.
            # does not raise), then handlers run without further ACL checks (they're
            # free to do some in their own implementations, though).
            handler = getattr(router, method_metadata.name)(args, token=token)

            if handler.args_type != method_metadata.args_type:
                raise RuntimeError(
                    "Handler args type doesn't match "
                    "method args type: %s vs %s" %
                    (handler.args_type, method_metadata.args_type))

            binary_result_type = (
                api_call_router.RouterMethodMetadata.BINARY_STREAM_RESULT_TYPE)

            if (handler.result_type != method_metadata.result_type and
                    not (handler.result_type is None and
                         method_metadata.result_type == binary_result_type)):
                raise RuntimeError(
                    "Handler result type doesn't match "
                    "method result type: %s vs %s" %
                    (handler.result_type, method_metadata.result_type))

            # HEAD method is only used for checking the ACLs for particular API
            # methods.
            if request.method == "HEAD":
                # If the request would return a stream, we add the Content-Length
                # header to the response.
                if (method_metadata.result_type ==
                        method_metadata.BINARY_STREAM_RESULT_TYPE):
                    binary_stream = handler.Handle(args, token=token)
                    return self._BuildResponse(
                        200, {"status": "OK"},
                        method_name=method_metadata.name,
                        no_audit_log=method_metadata.no_audit_log_required,
                        content_length=binary_stream.content_length,
                        token=token)
                else:
                    return self._BuildResponse(
                        200, {"status": "OK"},
                        method_name=method_metadata.name,
                        no_audit_log=method_metadata.no_audit_log_required,
                        token=token)

            if (method_metadata.result_type ==
                    method_metadata.BINARY_STREAM_RESULT_TYPE):
                binary_stream = handler.Handle(args, token=token)
                return self._BuildStreamingResponse(
                    binary_stream, method_name=method_metadata.name)
            else:
                format_mode = GetRequestFormatMode(request, method_metadata)
                result = self.CallApiHandler(handler, args, token=token)
                rendered_data = self._FormatResultAsJson(
                    result, format_mode=format_mode)

                return self._BuildResponse(
                    200,
                    rendered_data,
                    method_name=method_metadata.name,
                    no_audit_log=method_metadata.no_audit_log_required,
                    token=token)
        except access_control.UnauthorizedAccess as e:
            logging.exception("Access denied to %s (%s) with %s: %s",
                              request.path, request.method,
                              method_metadata.name, e)

            additional_headers = {
                "X-GRR-Unauthorized-Access-Reason":
                utils.SmartStr(e.message).replace("\n", ""),
                "X-GRR-Unauthorized-Access-Subject":
                utils.SmartStr(e.subject)
            }
            return self._BuildResponse(
                403,
                dict(message="Access denied by ACL: %s" % e.message,
                     subject=utils.SmartStr(e.subject)),
                headers=additional_headers,
                method_name=method_metadata.name,
                no_audit_log=method_metadata.no_audit_log_required,
                token=token)
        except api_call_handler_base.ResourceNotFoundError as e:
            return self._BuildResponse(
                404,
                dict(message=e.message),
                method_name=method_metadata.name,
                no_audit_log=method_metadata.no_audit_log_required,
                token=token)
        except NotImplementedError as e:
            return self._BuildResponse(
                501,
                dict(message=e.message),
                method_name=method_metadata.name,
                no_audit_log=method_metadata.no_audit_log_required,
                token=token)
        except Exception as e:  # pylint: disable=broad-except
            logging.exception("Error while processing %s (%s) with %s: %s",
                              request.path, request.method,
                              handler.__class__.__name__, e)
            return self._BuildResponse(
                500,
                dict(message=str(e), traceBack=traceback.format_exc()),
                method_name=method_metadata.name,
                no_audit_log=method_metadata.no_audit_log_required,
                token=token)
コード例 #27
0
ファイル: aff4.py プロジェクト: vismid86/grr
 def __str__(self):
   return utils.SmartStr(",".join(self.names))
コード例 #28
0
ファイル: flow.py プロジェクト: x35029/grr
  def Handle(self, args, token=None):
    if not args.client_id:
      raise ValueError("client_id must be provided")

    runner_args = args.flow.runner_args
    flow_name = args.flow.name
    if not flow_name:
      flow_name = runner_args.flow_name
    if not flow_name:
      raise RuntimeError("Flow name is not specified.")

    # Clear all fields marked with HIDDEN, except for output_plugins - they are
    # marked HIDDEN, because we have a separate UI for them, not because they
    # shouldn't be shown to the user at all.
    #
    # TODO(user): Refactor the code to remove the HIDDEN label from
    # FlowRunnerArgs.output_plugins.
    runner_args.ClearFieldsWithLabel(
        rdf_structs.SemanticDescriptor.Labels.HIDDEN,
        exceptions="output_plugins")

    if args.original_flow:
      runner_args.original_flow = rdf_objects.FlowReference(
          flow_id=utils.SmartStr(args.original_flow.flow_id),
          client_id=utils.SmartStr(args.original_flow.client_id))

    if data_store.RelationalDBFlowsEnabled():
      flow_cls = registry.FlowRegistry.FlowClassByName(flow_name)
      cpu_limit = None
      if runner_args.HasField("cpu_limit"):
        cpu_limit = runner_args.cpu_limit
      network_bytes_limit = None
      if runner_args.HasField("network_bytes_limit"):
        network_bytes_limit = runner_args.network_bytes_limit

      flow_id = flow.StartFlow(
          client_id=str(args.client_id),
          cpu_limit=cpu_limit,
          creator=token.username,
          flow_args=args.flow.args,
          flow_cls=flow_cls,
          network_bytes_limit=network_bytes_limit,
          original_flow=runner_args.original_flow,
          output_plugins=runner_args.output_plugins,
          parent_flow_obj=None,
      )
      flow_obj = data_store.REL_DB.ReadFlowObject(str(args.client_id), flow_id)

      res = ApiFlow().InitFromFlowObject(flow_obj)
      res.context = None
      return res
    else:
      flow_id = flow.StartAFF4Flow(
          client_id=args.client_id.ToClientURN(),
          flow_name=flow_name,
          token=token,
          args=args.flow.args,
          runner_args=runner_args)

      fd = aff4.FACTORY.Open(flow_id, aff4_type=flow.GRRFlow, token=token)
      return ApiFlow().InitFromAff4Object(fd, flow_id=flow_id.Basename())
コード例 #29
0
ファイル: artifact_registry.py プロジェクト: netspaces/grr
 def GetRegisteredArtifactNames(self):
     return [utils.SmartStr(x) for x in self._artifacts]
コード例 #30
0
ファイル: hunt.py プロジェクト: hfakar/grr
 def ObjectReference(self):
     return rdf_objects.ObjectReference(
         reference_type=rdf_objects.ObjectReference.Type.HUNT,
         hunt=rdf_objects.HuntReference(
             hunt_id=utils.SmartStr(self.hunt_id)))