def NotifyUp(self, packet):
        if packet.payload[0]:
            if getattr(packet.destination, 'service', None) is not None:
                if session.contextOnly and packet.command != const.cluster.MACHONETMSG_TYPE_SESSIONCHANGENOTIFICATION and packet.command != const.cluster.MACHONETMSG_TYPE_SESSIONINITIALSTATENOTIFICATION:
                    packet.srcTransport.InstallSessionIfRequired(
                        packet.destination.service, packet.payload[1])
                packet.srcTransport = None
                method = getattr(packet.service, packet.payload[1])
                callTimer = base.CallTimer(
                    '%s::%s (ServiceNotify\\Server)' %
                    (packet.destination.service, packet.payload[1]))
                try:
                    if len(packet.payload) == 3:
                        ClockThisWithoutTheStars(
                            'Remote Service Notify::%s::%s' %
                            (packet.destination.service, packet.payload[1]),
                            method, packet.payload[2])
                    else:
                        ClockThisWithoutTheStars(
                            'Remote Service Notify::%s::%s' %
                            (packet.destination.service, packet.payload[1]),
                            method, packet.payload[2], packet.payload[3])
                finally:
                    callTimer.Done()

                return
        else:
            packet.payload = packet.payload[1]
        return self.ForwardNotifyUp(packet)
Exemple #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)
Exemple #3
0
    def CallUp(self, packet):
        if packet.payload[0]:
            if getattr(packet.destination, 'service', None) is not None:
                if packet.payload[1] in packet.service.__dict__.get('__restrictedcalls__', {}) or packet.payload[1].startswith('_'):
                    raise RuntimeError('This call can only be the result of a hack attack', packet.payload[1])
                if packet.payload[1] == 'MachoBindObject':
                    args = packet.payload[2][:-1]
                    nodeID = packet.service.MachoResolveObject(args[0], 0)
                    if nodeID and nodeID != self.machoNet.GetNodeID():
                        self.machoNet.LogError('MachoBindObject received on wrong node.  Should have gone to ', nodeID, ', bindParams=', args[0], ', packet=', packet)
                        raise WrongMachoNode(nodeID)
                    call = packet.payload[2][-1]
                    boundObject = packet.service.MachoGetObjectBoundToSession(packet.payload[2][0], session)
                    if self.logClientCall and packet.source.addressType == const.ADDRESS_TYPE_CLIENT:
                        kwargs = packet.payload[3] if len(packet.payload) >= 4 else None
                        self.machoNet.LogClientCall(session, packet.destination.service, packet.payload[1], packet.payload[2], kwargs)
                    if call is not None:
                        if isinstance(boundObject, base.ObjectConnection):
                            objclass = boundObject.GetObjectConnectionLogClass()
                        else:
                            objclass = macho.AssignLogName(object)
                        method, args, keywords = call
                        if method in boundObject.__dict__.get('__restrictedcalls__', {}) or method.startswith('_'):
                            raise RuntimeError('This call can only be the result of a hack attack', method)
                        callTimer = base.CallTimer('%s::%s (UnBoundObjectCall\\Server)' % (objclass, method))
                        try:
                            func = getattr(boundObject, method)
                            self.UpdateRecvServiceCallStats(objclass, method, packet.source)
                            if not keywords:
                                retval = ClockThisWithoutTheStars('Remote Unbound Object Call::%s::%s' % (objclass, method), func, args)
                            else:
                                retval = ClockThisWithoutTheStars('Remote Unbound Object Call::%s::%s' % (objclass, method), func, args, keywords)
                            payload = (boundObject, retval)
                        finally:
                            callTimer.Done()

                    else:
                        payload = (boundObject, None)
                else:
                    args = packet.payload[2]
                    method = getattr(packet.service, packet.payload[1])
                    callTimer = base.CallTimer('%s::%s (ServiceCall\\Server)' % (packet.destination.service, packet.payload[1]))
                    if self.logClientCall and packet.source.addressType == const.ADDRESS_TYPE_CLIENT and packet.payload[1] != 'MachoBindObject':
                        kwargs = packet.payload[3] if len(packet.payload) >= 4 else None
                        self.machoNet.LogClientCall(session, packet.destination.service, packet.payload[1], args, kwargs)
                    try:
                        self.UpdateRecvServiceCallStats(packet.destination.service, method.__method__, packet.source)
                        if len(packet.payload) == 3:
                            payload = ClockThisWithoutTheStars('Remote Service Call::%s::%s' % (packet.destination.service, packet.payload[1]), method, args)
                        else:
                            payload = ClockThisWithoutTheStars('Remote Service Call::%s::%s' % (packet.destination.service, packet.payload[1]), method, args, packet.payload[3])
                    finally:
                        callTimer.Done()

                if session.contextOnly:
                    packet.srcTransport.InstallSessionIfRequired(packet.destination.service, packet.payload[1])
                packet.srcTransport = None
                return packet.Response(payload=payload)
        else:
            packet.payload = packet.payload[1]
        return self.ForwardCallUp(packet)
Exemple #4
0
    def CallUp(self, packet):
        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
Exemple #5
0
    def NotifySessionChangeWithoutTheStars(self, eventid, args, keywords=None):
        if keywords is None:
            keywords = {}
        if eventid not in ('DoSessionChanging', 'ProcessSessionChange',
                           'OnSessionChanged'):
            raise RuntimeError(
                'NotifySessionChange called with eventid ', eventid,
                '. Must be one of DoSessionChanging, ProcessSessionChange or OnSessionChanged'
            )
        if eventid == 'ProcessSessionChange' and stackless.getcurrent(
        ).block_trap or stackless.getcurrent().is_main:
            raise RuntimeError(
                "ChainEvent (NotifySessionChange) is blocking by design, but you're block trapped."
            )
        if eventid == 'DoSessionChanging':
            old_block_trap = stackless.getcurrent().block_trap
            stackless.getcurrent().block_trap = 1
        shouldLogMethodCalls = self.ShouldLogMethodCalls()
        if shouldLogMethodCalls:
            self.LogMethodCall('NotifySessionChange(', eventid, ',*args=',
                               args, ',**kw=', keywords, ')')
        prefix = blue.pyos.taskletTimer.GetCurrent(
        ) + '::NotifySessionChange_' + eventid + '::'
        ret = []
        myNodeID = self.services['machoNet'].GetNodeID()
        isSessionRelevant = boot.role != 'server' or session.contextOnly
        try:
            for srv in self.notify.get(eventid, []):
                try:
                    logname = prefix + self.GetLogName(srv)
                    if ObjectShouldReceiveMessages(srv):
                        if shouldLogMethodCalls:
                            self.LogMethodCall('Calling ' + logname)
                        if eventid == 'OnSessionChanged':
                            if not isSessionRelevant and srv.MachoResolve(
                                    session.GetActualSession()) == myNodeID:
                                isSessionRelevant = True
                            srvGuid = getattr(srv, '__guid__', logname)
                            uthread.worker(prefix + srvGuid,
                                           self.MollycoddledUthread,
                                           srvGuid, eventid,
                                           getattr(srv,
                                                   eventid), args, keywords)
                        else:
                            retval = ClockThisWithoutTheStars(
                                logname, getattr(srv, eventid), args, keywords)
                            ret.append(retval)
                    elif shouldLogMethodCalls:
                        self.LogMethodCall('Skipping ', logname,
                                           ' (service not running)')
                except StandardError:
                    log.LogException('In %s.%s' % (getattr(
                        srv, '__guid__', self.GetLogName(srv)), eventid))
                    sys.exc_clear()

            notifiedToRemove = []
            for weakObj in self.notifyObs.get(eventid, []):
                obj = weakObj()
                if obj is None or not getattr(obj, eventid, None):
                    notifiedToRemove.append(weakObj)
                else:
                    try:
                        if shouldLogMethodCalls:
                            logname = prefix + str(obj)
                            self.LogMethodCall('Calling ', logname)
                        if eventid == 'OnSessionChanged':
                            uthread.workerWithoutTheStars(
                                '', getattr(obj, eventid), args, keywords)
                        else:
                            ClockThisWithoutTheStars(
                                prefix + self.GetLogName(weakObj),
                                getattr(obj, eventid), args, keywords)
                    except StandardError:
                        self.LogError('In %s.%s' %
                                      (getattr(weakObj, '__guid__',
                                               self.GetLogName(srv)), eventid))
                        log.LogException()
                        sys.exc_clear()

            for toRemove in notifiedToRemove:
                if toRemove in self.notifyObs[eventid]:
                    self.notifyObs[eventid].remove(toRemove)

            if not session.contextOnly:
                if not isSessionRelevant:
                    if session.irrelevanceTime is None:
                        session.irrelevanceTime = blue.os.GetWallclockTime()
                        log.LogInfo('CTXSESS: session ', session.sid, ' = ',
                                    session,
                                    ' is no longer relevant to any service')
                elif session.irrelevanceTime is not None:
                    log.LogInfo('CTXSESS: session ', session.sid,
                                ' became relevant again')
                    session.irrelevanceTime = None
        finally:
            if eventid == 'DoSessionChanging':
                bt = 0
                if old_block_trap:
                    bt = 1
                stackless.getcurrent().block_trap = bt

        return tuple(ret)
Exemple #6
0
    def ChainEventWithoutTheStars(self, eventid, args, keywords=None):
        if keywords is None:
            keywords = {}
        if not eventid.startswith('Process'):
            self.LogError(
                'ChainEvent called with event ', eventid,
                ".  All events sent via ChainEvent should start with 'Process'"
            )
            self.LogError(
                "Not only is the programmer responsible for this a 10z3r, but he wears his mother's underwear as well"
            )
            log.LogTraceback()
        if stackless.getcurrent().block_trap or stackless.getcurrent().is_main:
            raise RuntimeError(
                "ChainEvent is blocking by design, but you're block trapped.  You have'll have to find some alternative means to do Your Thing, dude."
            )
        if not self.notify.get(eventid, []) and not self.notifyObs.get(
                eventid, []):
            self.LogInfo("Orphan'd event.  ", eventid,
                         "doesn't have any listeners")
        shouldLogMethodCalls = self.ShouldLogMethodCalls()
        if shouldLogMethodCalls:
            self.LogMethodCall('ChainEvent(', eventid, ',*args=', args,
                               ',**kw=', keywords, ')')
        prefix = blue.pyos.taskletTimer.GetCurrent(
        ) + '::ChainEvent_' + eventid + '::'
        ret = []
        for srv in self.notify.get(eventid, []):
            contextName = self.GetLogName(srv)
            try:
                logname = prefix + contextName
                if ObjectShouldReceiveMessages(srv):
                    if shouldLogMethodCalls:
                        self.LogMethodCall('Calling ', logname)
                    retval = ClockThisWithoutTheStars(logname,
                                                      getattr(srv, eventid),
                                                      args, keywords)
                    ret.append(retval)
                elif shouldLogMethodCalls:
                    self.LogMethodCall('Skipping ', logname,
                                       ' (service not running)')
            except StandardError:
                self.LogError('In %s.%s' % (contextName, eventid))
                log.LogException()
                sys.exc_clear()

        notifiedToRemove = []
        for weakObj in self.notifyObs.get(eventid, []):
            obj = weakObj()
            if obj is None:
                notifiedToRemove.append(weakObj)
            else:
                contextName = self.GetLogName(weakObj)
                try:
                    logname = prefix + contextName
                    if shouldLogMethodCalls:
                        self.LogMethodCall('Calling ', prefix + str(obj))
                    ClockThisWithoutTheStars(logname, getattr(obj, eventid),
                                             args, keywords)
                except StandardError:
                    self.LogError('In %s.%s:' % (contextName, eventid))
                    log.LogException()
                    sys.exc_clear()

        for toRemove in notifiedToRemove:
            if toRemove in self.notifyObs[eventid]:
                self.notifyObs[eventid].remove(toRemove)

        return tuple(ret)
Exemple #7
0
    def SendEventWithoutTheStars(self, eventid, args, keywords=None):
        if keywords is None:
            keywords = {}
        if not eventid.startswith('Do'):
            self.LogError(
                'SendEvent called with event ', eventid,
                ".  All events sent via SendEvent should start with 'Do'")
            self.LogError(
                "Not only is the programmer responsible for this a 10z3r, but he wears his mother's underwear as well"
            )
            log.LogTraceback()
        if not self.notify.get(eventid, []) and not self.notifyObs.get(
                eventid, []):
            self.LogInfo("Orphan'd event.  ", eventid,
                         "doesn't have any listeners")
        shouldLogMethodCalls = self.ShouldLogMethodCalls()
        if shouldLogMethodCalls:
            if IsFullLogging():
                self.LogMethodCall('SendEvent(', eventid, ',*args=', args,
                                   ',**kw=', keywords, ')')
            else:
                self.LogMethodCall('SendEvent(', eventid, ')')
        prefix = blue.pyos.taskletTimer.GetCurrent(
        ) + '::SendEvent_' + eventid + '::'
        old_block_trap = stackless.getcurrent().block_trap
        stackless.getcurrent().block_trap = 1
        ret = []
        try:
            for srv in self.notify.get(eventid, []):
                try:
                    logname = prefix + self.GetLogName(srv)
                    if ObjectShouldReceiveMessages(srv):
                        if shouldLogMethodCalls:
                            self.LogMethodCall('Calling ', logname)
                        ret.append(
                            ClockThisWithoutTheStars(logname,
                                                     getattr(srv, eventid),
                                                     args, keywords))
                    elif shouldLogMethodCalls:
                        self.LogMethodCall('Skipping ', logname,
                                           ' (service not running)')
                except StandardError:
                    self.LogError('In %s.%s' %
                                  (getattr(srv, '__guid__', logname), eventid))
                    log.LogException()
                    sys.exc_clear()

            notifiedToRemove = []
            for weakObj in self.notifyObs.get(eventid, []):
                obj = weakObj()
                if obj is None:
                    notifiedToRemove.append(weakObj)
                else:
                    try:
                        if shouldLogMethodCalls:
                            logname = prefix + str(obj)
                            self.LogMethodCall('Calling ', logname)
                        apply(getattr(obj, eventid), args, keywords)
                    except StandardError:
                        self.LogError(
                            'In %s.%s' %
                            (getattr(weakObj, '__guid__',
                                     self.GetLogName(weakObj)), eventid))
                        log.LogException()
                        sys.exc_clear()

            for toRemove in notifiedToRemove:
                if toRemove in self.notifyObs[eventid]:
                    self.notifyObs[eventid].remove(toRemove)

        finally:
            bt = 0
            if old_block_trap:
                bt = 1
            stackless.getcurrent().block_trap = bt
            return tuple(ret)