def evaluate(self, context): """ <Purpose> Evaluates the wrapped code within a context. <Arguments> context: A global context to use when executing the code. This should be a SafeDict object, but if a dict object is provided it will automatically be converted to a SafeDict object. <Exceptions> Any that may be raised by the code that is being evaluated. A RepyArgumentError exception will be raised if the provided context is not a safe dictionary object or a ContextUnsafeError if the context is a dict but cannot be converted into a SafeDict. <Returns> The context dictionary that was used during evaluation. If the context was a dict object, this will be a new SafeDict object. If the context was a SafeDict object, then this will return the same context object. """ # Try to convert a normal dict into a SafeDict if type(context) is dict: try: context = safe.SafeDict(context) except Exception, e: raise ContextUnsafeError, "Provided context is not safe! Exception: " + str( e)
def main(restrictionsfn, program, args): # Armon: Initialize the circular logger before forking in init_restrictions() if logfile: # time to set up the circular logger loggerfo = loggingrepy.circular_logger(logfile) # and redirect err and out there... sys.stdout = loggerfo sys.stderr = loggerfo else: # let's make it so that the output (via print) is always flushed sys.stdout = loggingrepy.flush_logger(sys.stdout) # start the nanny up and read the restrictions files. restrictions.init_restrictions(restrictionsfn) # Armon: Update our IP cache emulcomm.update_ip_cache() # These will be the functions and variables in the user's namespace (along # with the builtins allowed by the safe module). usercontext = {'mycontext':{}} # Add to the user's namespace wrapped versions of the API functions we make # available to the untrusted user code. namespace.wrap_and_insert_api_functions(usercontext) # Convert the usercontext from a dict to a SafeDict usercontext = safe.SafeDict(usercontext) # Allow some introspection by providing a reference to the context usercontext["_context"] = usercontext # let's try three times to load the file... for attempts in range(3): try: # grab the user code from the file usercode = file(program).read() # and then exit the loop on success break except (OSError, IOError), e: # Might be an interrupted system call, if so retry... (#840) if 'nterrupred system call' in str(e): continue print "Failed to read the specified file: '"+program+"'" raise except:
def run_unrestricted_repy_code(filename, args_list=[]): """ <Purpose> This function allows an user to run a repy file without using any restrictions like a normal repy program. <Arguments> filename - The filename of the repy file you want to run. args_list - a list of arguments that need to be passed in to the repy file. <Exceptions> Exception raised if args_list provided is not in the list form. Any exception raised by the repy file will be raised. Error may be raised if the code in the repy file is not safe. <Return> None """ if not isinstance(args_list, list): raise Exception("args_list must be of list type!") # Initialize the safe module before building the context. _initialize_safe_module() # Prepare the callargs list callargs_list = [filename] callargs_list.extend(args_list) # Prepare the context. context = {} namespace.wrap_and_insert_api_functions(context) context = safe.SafeDict(context) context["_context"] = context context[ "createvirtualnamespace"] = virtual_namespace.createvirtualnamespace context["getlasterror"] = emulmisc.getlasterror context['callfunc'] = 'initialize' context['callargs'] = callargs_list code = open("dylink.repy").read() virt = virtual_namespace.VirtualNamespace(code, name="dylink_code") result = virt.evaluate(context)
def get_safe_context(args): # These will be the functions and variables in the user's namespace (along # with the builtins allowed by the safe module). usercontext = {'mycontext': {}} # Add to the user's namespace wrapped versions of the API functions we make # available to the untrusted user code. namespace.wrap_and_insert_api_functions(usercontext) # Convert the usercontext from a dict to a SafeDict usercontext = safe.SafeDict(usercontext) # Allow some introspection by providing a reference to the context usercontext["_context"] = usercontext # call the initialize function usercontext['callfunc'] = 'initialize' usercontext['callargs'] = args[:] return usercontext
def get_safe_context(args): # These will be the functions and variables in the user's namespace (along # with the builtins allowed by the safe module). usercontext = {'mycontext': {}} # Add to the user's namespace wrapped versions of the API functions we make # available to the untrusted user code. namespace.wrap_and_insert_api_functions(usercontext) # Convert the usercontext from a dict to a SafeDict usercontext = safe.SafeDict(usercontext) # Allow some introspection by providing a reference to the context usercontext["_context"] = usercontext # BAD:REMOVE all API imports usercontext["getresources"] = nonportable.get_resources #usercontext["openfile"] = emulfile.emulated_open #usercontext["listfiles"] = emulfile.listfiles #usercontext["removefile"] = emulfile.removefile #usercontext["exitall"] = emulmisc.exitall #usercontext["createlock"] = emulmisc.createlock #usercontext["getruntime"] = emulmisc.getruntime #usercontext["randombytes"] = emulmisc.randombytes #usercontext["createthread"] = emultimer.createthread #usercontext["sleep"] = emultimer.sleep #usercontext["getthreadname"] = emulmisc.getthreadname usercontext[ "createvirtualnamespace"] = virtual_namespace.createvirtualnamespace usercontext["getlasterror"] = emulmisc.getlasterror usercontext["json_parse"] = json.loads # call the initialize function usercontext['callfunc'] = 'initialize' usercontext['callargs'] = args[:] return usercontext
def init_namespace(resourcefn, program, args): global idlethreadcount, event_id # Armon: Initialize the circular logger before starting the nanny if logfile: # time to set up the circular logger loggerfo = loggingrepy.circular_logger(logfile) # and redirect err and out there... sys.stdout = loggerfo sys.stderr = loggerfo else: # let's make it so that the output (via print) is always flushed sys.stdout = loggingrepy.flush_logger(sys.stdout) # start the nanny up and read the resource file. nanny.start_resource_nanny(resourcefn) # now, let's fire up the cpu / disk / memory monitor... # nonportable.monitor_cpu_disk_and_mem() # Armon: Update our IP cache emulcomm.update_ip_cache() # These will be the functions and variables in the user's namespace (along # with the builtins allowed by the safe module). usercontext = {'mycontext': {}} # Add to the user's namespace wrapped versions of the API functions we make # available to the untrusted user code. namespace.wrap_and_insert_api_functions(usercontext) # Convert the usercontext from a dict to a SafeDict usercontext = safe.SafeDict(usercontext) # Allow some introspection by providing a reference to the context usercontext["_context"] = usercontext # BAD:REMOVE all API imports usercontext["getresources"] = nonportable.get_resources usercontext["mycontext"]["wallclocktime"] = time.time #usercontext["openfile"] = emulfile.emulated_open #usercontext["listfiles"] = emulfile.listfiles #usercontext["removefile"] = emulfile.removefile #usercontext["exitall"] = emulmisc.exitall #usercontext["createlock"] = emulmisc.createlock #usercontext["getruntime"] = emulmisc.getruntime #usercontext["randombytes"] = emulmisc.randombytes #usercontext["createthread"] = emultimer.createthread #usercontext["sleep"] = emultimer.sleep #usercontext["getthreadname"] = emulmisc.getthreadname usercontext[ "createvirtualnamespace"] = virtual_namespace.createvirtualnamespace usercontext["getlasterror"] = emulmisc.getlasterror # grab the user code from the file try: usercode = file(program).read() except: print "Failed to read the specified file: '" + program + "'" raise # Armon: Create the main namespace try: main_namespace = virtual_namespace.VirtualNamespace(usercode, program) except CodeUnsafeError, e: print "Specified repy program is unsafe!" print "Static-code analysis failed with error: " + str(e) harshexit.harshexit(5)
from emulmisc import * from emulcomm import * from emulfile import * from emultimer import * # Buld the _context and usercontext dicts. # These will be the functions and variables in the user's namespace (along # with the builtins allowed by the safe module). usercontext = {'mycontext': {}} # Add to the user's namespace wrapped versions of the API functions we make # available to the untrusted user code. namespace.wrap_and_insert_api_functions(usercontext) # Convert the usercontext from a dict to a SafeDict usercontext = safe.SafeDict(usercontext) # Allow some introspection by providing a reference to the context usercontext["_context"] = usercontext usercontext["getresources"] = nonportable.get_resources usercontext[ "createvirtualnamespace"] = virtual_namespace.createvirtualnamespace usercontext["getlasterror"] = emulmisc.getlasterror _context = usercontext.copy() # This is needed because otherwise we're using the old versions of file and # open. We should change the names of these functions when we design # repy 0.2 originalopen = open originalfile = file openfile = emulated_open