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)
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