Example #1
0
 def __GetObjectTypeAndGuts(self, object):
     ob = object
     if isinstance(object, base.ObjectConnection):
         ob = object.__dict__['__object__']
         objclass = object.GetObjectConnectionLogClass()
     else:
         objclass = macho.AssignLogName(object)
     return (objclass, ob)
Example #2
0
    def NotifyUp(self, packet):
        if packet.payload[0] == 1:
            tup = self.FromPickle(packet.payload[1], packet.source)
            objectID, method, args = tup[0], tup[1], tup[2]
            if method == 'ClientHasReleasedTheseObjects':
                oidsandrefs = objectID
                for each in oidsandrefs:
                    objectID, refID = each
                    if objectID in session.machoObjectsByID:
                        object = session.machoObjectsByID[objectID][1]
                        objectType, guts = self.__GetObjectTypeAndGuts(object)
                        session.UnregisterMachoObject(objectID, refID)

                return
            else:
                if objectID[0] == 'C' and macho.mode == 'client':
                    cid, oid = objectID.split(':')
                    objectID = '%s:%s' % (self.identifier, oid)
                if objectID not in session.machoObjectsByID:
                    raise UnMachoDestination(
                        'The specified object (%s) is not a member of this session'
                        % objectID)
                object = session.machoObjectsByID[objectID][1]
                if isinstance(object, base.ObjectConnection):
                    objclass = object.GetObjectConnectionLogClass()
                else:
                    objclass = macho.AssignLogName(object)
                callTimer = base.CallTimer('%s::%s (ObjectNotify\\Server)' %
                                           (objclass, method))
                try:
                    func = getattr(object, method)
                    if method in object.__dict__.get(
                            '__restrictedcalls__',
                        {}) or method.startswith('_'):
                        raise RuntimeError(
                            'This call can only be the result of a hack attack',
                            method)
                    if not isinstance(object, base.ObjectConnection) and len(
                            tup) == 4 and 'machoVersion' in tup[3]:
                        if len(tup[3]) == 1:
                            tup = (tup[0], tup[1], tup[2])
                        else:
                            del tup[3]['machoVersion']
                    if len(tup) == 3:
                        ClockThisWithoutTheStars(
                            'Remote Object Notify::%s::%s' %
                            (objclass, method), func, args)
                    else:
                        ClockThisWithoutTheStars(
                            'Remote Object Notify::%s::%s' %
                            (objclass, method), func, args, tup[3])
                finally:
                    callTimer.Done()

                return
        else:
            packet.payload = self.FromPickle(packet.payload[1], packet.source)
        self.ForwardNotifyUp(packet)
 def __GetObjectTypeAndGuts(self, object):
     """
         Helper function to rip the type name and the actual object out of an object or proxy object
     """
     ob = object
     if isinstance(object, base.ObjectConnection):
         ob = object.__dict__['__object__']
         objclass = object.GetObjectConnectionLogClass()
     else:
         objclass = macho.AssignLogName(object)
     return (objclass, ob)
    def CallUp(self, packet):
        """
            Handles calls to objects, in addition to solving the "inner pickle" problem.
        """
        if packet.command == const.cluster.MACHONETMSG_TYPE_AUTHENTICATION_REQ:
            retval = self.ForwardCallUp(packet)
            self.__StringifyPayloadForLogging(retval, retval.payload)
            retval.payload = self.ToPickle(retval.payload)
            if self.added_objects:
                retval.oob['OID+'] = self.added_objects
            retval.compressedPart = self.compressedPart
            return retval
        elif packet.payload[0]:
            tup = self.FromPickle(packet.payload[1], packet.source)
            objectID, method, args = tup[0], tup[1], tup[2]
            if objectID[0] == 'C' and macho.mode == 'client':
                cid, oid = objectID.split(':')
                objectID = '%s:%s' % (self.identifier, oid)
            if objectID not in session.machoObjectsByID:
                session.DumpSession(
                    'OBJECTNOTMEMBER',
                    'The specified object (%s) is not a member of this session'
                    % objectID)
                raise UnMachoDestination(
                    'The specified object (%s) is not a member of this session'
                    % objectID)
            object = session.machoObjectsByID[objectID][1]
            if isinstance(object, base.ObjectConnection):
                objclass = object.GetObjectConnectionLogClass()
            else:
                objclass = macho.AssignLogName(object)
            callTimer = base.CallTimer('%s::%s (ObjectCall\\Server)' %
                                       (objclass, method))
            if self.logClientCall and packet.source.addressType == const.ADDRESS_TYPE_CLIENT:
                kwargs = tup[3] if len(tup) >= 4 else None
                self.machoNet.LogClientCall(session, objclass, method, args,
                                            kwargs)
            try:
                func = getattr(object, method)
                if method in object.__dict__.get('__restrictedcalls__',
                                                 {}) or method.startswith('_'):
                    raise RuntimeError(
                        'This call can only be the result of a hack attack',
                        method)
                if not isinstance(object, base.ObjectConnection):
                    if 0 == session.role & service.ROLE_SERVICE and hasattr(
                            object, '__exportedcalls__'
                    ) and method not in object.__exportedcalls__:
                        raise RuntimeError(
                            '%s call is not exported from this pass-by-reference object.'
                            % method)
                    if not session.role & service.ROLE_SERVICE:
                        paramList = object.__exportedcalls__.get(method, None)
                        paramDict = None
                        if paramList is not None:
                            if type(paramList) is list:
                                if len(paramList):
                                    tmp = {}
                                    tmp['role'] = paramList[0]
                                    tmp['preargs'] = paramList[1:]
                                    paramDict = tmp
                            elif type(paramList) is dict:
                                paramDict = paramList
                        if paramDict is not None:
                            role = paramDict.get('role', service.ROLE_SERVICE)
                            if not role & session.role:
                                session.LogSessionError(
                                    "Called %s::%s, which requires role 0x%x, which the user doesn't have. User has role 0x%x"
                                    % (object.__class__.__name__, method, role,
                                       session.role))
                                raise RuntimeError(
                                    'RoleNotAssigned',
                                    "%s::%s requires role 0x%x, which the user doesn't have. User has role 0x%x. Calling session: %s"
                                    % (object.__class__.__name__, method, role,
                                       session.role, str(session)))
                            preargs = paramDict.get('preargs', [])
                            args2 = len(preargs) * [None] + list(args)
                            for i in range(len(preargs)):
                                args2[i] = getattr(session, preargs[i])

                            args = tuple(args2)
                    if len(tup) == 4 and 'machoVersion' in tup[3]:
                        if len(tup[3]) == 1:
                            tup = (tup[0], tup[1], tup[2])
                        else:
                            del tup[3]['machoVersion']
                if len(tup) == 3:
                    retval = ClockThisWithoutTheStars(
                        'Remote Object Call::%s::%s' % (objclass, method),
                        func, args)
                else:
                    retval = ClockThisWithoutTheStars(
                        'Remote Object Call::%s::%s' % (objclass, method),
                        func, args, tup[3])
                retpickle = self.ToPickle(retval)
                retval = packet.Response(payload=retpickle)
                if self.added_objects:
                    retval.oob['OID+'] = self.added_objects
                self.__StringifyPayloadForLogging(retval, retpickle)
                retval.compressedPart = self.compressedPart
            finally:
                callTimer.Done()

            return retval
        else:
            packet.payload = self.FromPickle(packet.payload[1], packet.source)
            retval = self.ForwardCallUp(packet)
            self.__StringifyPayloadForLogging(retval, retval.payload)
            retval.payload = self.ToPickle(retval.payload)
            if self.added_objects:
                retval.oob['OID+'] = self.added_objects
            retval.compressedPart = self.compressedPart
            return retval