def exists_outgoing_network_socket(localip, localport, remoteip, remoteport): """ <Purpose> Determines if there exists a network socket with the specified unique tuple. Assumes TCP. <Arguments> localip: The IP address of the local socket localport: The port of the local socket remoteip: The IP of the remote host remoteport: The port of the remote host <Returns> A Tuple, indicating the existence and state of the socket. E.g. (Exists (True/False), State (String or None)) """ # This only works if all are not of the None type if not (localip and localport and remoteip and remoteport): return (False, None) # Construct search strings, add a space so port 8 wont match 80 localsocket = localip + ":" + str(localport) + " " remotesocket = remoteip + ":" + str(remoteport) + " " # Launch up a shell, get the feedback netstat_process = portable_popen.Popen(["netstat", "-an"]) netstat_output, _ = netstat_process.communicate() target_lines = textops.textops_grep(localsocket, \ textops.textops_rawtexttolines(netstat_output, linedelimiter="\r\n")) target_lines = textops.textops_grep(remotesocket, target_lines) target_lines = textops.textops_grep("tcp ", target_lines, case_sensitive=False) # Check each line, to make sure the local socket comes before the remote socket # Since we are just using find, the "order" is not imposed, so if the remote socket # is first that implies it is an inbound connection if len(target_lines) > 0: # Check each entry for line in target_lines: # Check the indexes for the local and remote socket, make sure local # comes first local_index = line.find(localsocket) remote_index = line.find(remotesocket) if local_index <= remote_index and local_index != -1: # Replace tabs with spaces, explode on spaces parts = line.replace("\t", "").strip("\r\n").split() # Get the state socket_state = parts[-1] return (True, socket_state) return (False, None) # If there were no entries, then there is no socket! else: return (False, None)
def restart_software_updater(): """ <Purpose> Attempts to start a new software updater, and will exit this one if the new one seems to start successfully. If the new one does not start successfully, then we just return. <Arguments> None <Exceptions> Possible exception if there is problems writing the OK file. <Side Effects> If all goes well, a new softwareupdater will be started, and this one will exit. <Returns> In the successful case, it will not return. If the new softwareupdater does not start correctly, we will return None. """ safe_log( "[restart_software_updater] Attempting to restart software updater.") # find an unused mutex thismutex = get_mutex() # starts new with arg that is the mutex junkupdaterobject = portable_popen.Popen( ["python", "softwareupdater.py", thismutex]) # wait for some time (1 minute) for them to init and stop them if they don't for junkcount in range(30): misc.do_sleep(2.0) # if "OK" file exists, release softwareupdater.old, remove OK file and exit if os.path.exists("softwareupdater.OK." + thismutex): runonce.releaseprocesslock('softwareupdater.old') os.remove("softwareupdater.OK." + thismutex) # I'm happy, it is taking over safe_log( "[restart_software_updater] The new instance of the software updater is running. This one is exiting." ) sys.exit(10) # else write "stop" file because it failed... file("softwareupdater.stop." + thismutex, "w").close() safe_log( "[restart_software_updater] Failed to restart software updater. This instance will continue." ) # I continue normal operation return
def exists_outgoing_network_socket(localip, localport, remoteip, remoteport): """ <Purpose> Determines if there exists a network socket with the specified unique tuple. Assumes TCP. <Arguments> localip: The IP address of the local socket localport: The port of the local socket remoteip: The IP of the remote host remoteport: The port of the remote host <Returns> A Tuple, indicating the existence and state of the socket. E.g. (Exists (True/False), State (String or None)) """ # This only works if all are not of the None type if not (localip and localport and remoteip and remoteport): return (False, None) # Grab netstat output. netstat_process = portable_popen.Popen(["netstat", "-an"]) netstat_stdout, _ = netstat_process.communicate() netstat_lines = textops.textops_rawtexttolines(netstat_stdout) # Search for things matching the local and remote ip+port we are trying to get # information about. target_lines = textops.textops_grep(localip + ':' + str(localport), netstat_lines) + \ textops.textops_grep(localip + '.' + str(localport), netstat_lines) target_lines = textops.textops_grep(remoteip + ':' + str(remoteport), target_lines) + \ textops.textops_grep(remoteip + '.' + str(remoteport), target_lines) # Only tcp connections. target_lines = textops.textops_grep('tcp', target_lines) # Check if there is any entries if len(target_lines) > 0: line = target_lines[0] # Replace tabs with spaces, explode on spaces parts = line.replace("\t", "").strip("\n").split() # Get the state socket_state = parts[-1] return (True, socket_state) else: return (False, None)
def restart_client(filenamelist): """ <Purpose> Restarts the node manager. <Arguments> filenamelist - Currently not used, but is included for possible future use. <Exceptions> None <Side Effects> The current node manager is killed, and a new one is started. <Returns> None. """ # kill nmmain if it is currently running retval = runonce.getprocesslock('seattlenodemanager') if retval == True: safe_log( "[restart_client] Obtained the lock 'seattlenodemanager', it wasn't running." ) # I got the lock, it wasn't running... # we want to start a new one, so lets release runonce.releaseprocesslock('seattlenodemanager') elif retval == False: # Someone has the lock, but I can't do anything... safe_log( "[restart_client] The lock 'seattlenodemanager' is held by an unknown process. Will try to start it anyways." ) else: safe_log("[restart_client] Stopping the nodemanager.") # I know the process ID! Let's stop the process... harshexit.portablekill(retval) safe_log("[restart_client] Starting the nodemanager.") # run the node manager. I rely on it to do the smart thing (handle multiple # instances, etc.) nm_restart_command_args_list = ["python", "nmmain.py"] if run_nodemanager_in_foreground: nm_restart_command_args_list.append('--foreground') junkprocessobject = portable_popen.Popen(nm_restart_command_args_list)
def get_system_thread_count(): """ <Purpose> Returns the number of active threads running on the system. <Returns> The thread count. """ # Use PS since it is can get the info for us process = portable_popen.Popen(["ps", "axH"]) ps_output, _ = process.communicate() # Subtract 1 from the number of lines because the first line is a a table # header: " PID TTY STAT TIME COMMAND" threads = len(textops.textops_rawtexttolines(ps_output)) - 1 return threads
def exists_listening_network_socket(ip, port, tcp): """ <Purpose> Determines if there exists a network socket with the specified ip and port which is the LISTEN state. <Arguments> ip: The IP address of the listening socket port: The port of the listening socket tcp: Is the socket of TCP type, else UDP <Returns> True or False. """ # This only works if both are not of the None type if not (ip and port): return False # UDP connections are stateless, so for TCP check for the LISTEN state # and for UDP, just check that there exists a UDP port if tcp: find = ["tcp", "LISTEN"] else: find = ["udp"] # Launch up a shell, get the feed back netstat_process = portable_popen.Popen(["netstat", "-an"]) netstat_output, _ = netstat_process.communicate() target_lines = textops.textops_grep(ip+':'+str(port)+' ', \ textops.textops_rawtexttolines(netstat_output, linedelimiter="\r\n")) for term in find: # Add additional grep's target_lines = textops.textops_grep(term, target_lines, case_sensitive=False) # Convert to an integer num = len(target_lines) return (num > 0)
def exists_listening_network_socket(ip, port, tcp): """ <Purpose> Determines if there exists a network socket with the specified ip and port which is the LISTEN state. <Arguments> ip: The IP address of the listening socket port: The port of the listening socket tcp: Is the socket of TCP type, else UDP <Returns> True or False. """ # This only works if both are not of the None type if not (ip and port): return False # UDP connections are stateless, so for TCP check for the LISTEN state # and for UDP, just check that there exists a UDP port if tcp: grep_terms = ["tcp", "LISTEN"] else: grep_terms = ["udp"] # Launch up a shell, get the feedback netstat_process = portable_popen.Popen(["netstat", "-an"]) netstat_stdout, _ = netstat_process.communicate() netstat_lines = textops.textops_rawtexttolines(netstat_stdout) # Search for things matching the ip+port we are trying to get # information about. target_lines = textops.textops_grep(ip + ':' + str(port), netstat_lines) + \ textops.textops_grep(ip + '.' + str(port), netstat_lines) for term in grep_terms: target_lines = textops.textops_grep(term, target_lines) number_of_sockets = len(target_lines) return (number_of_sockets > 0)
def get_available_interfaces(): """ <Purpose> Returns a list of available network interfaces. <Returns> An array of string interfaces """ # Common headers # This list contains common header elements so that they can be stripped common_headers_list = ["Name", "Kernel", "Iface"] # Netstat will return all interfaces, but also has some duplication. # Cut will get the first field from each line, which is the interface name. # Sort prepares the input for uniq, which only works on sorted lists. # Uniq, is somewhat obvious, it will only return the unique interfaces to remove duplicates. # Launch up a shell, get the feedback netstat_process = portable_popen.Popen(["netstat", "-i"]) netstat_stdout, _ = netstat_process.communicate() netstat_lines = textops.textops_rawtexttolines(netstat_stdout) target_lines = textops.textops_cut(netstat_lines, delimiter=" ", fields=[0]) unique_lines = set(target_lines) # Create an array for the interfaces interfaces_list = [] for line in unique_lines: # Strip the newline line = line.strip("\n") # Check if this is a header if line in common_headers_list: continue interfaces_list.append(line) # Done, return the interfaces return interfaces_list
def get_interface_ip_addresses(interfaceName): """ <Purpose> Returns the IP address associated with the interface. <Arguments> interfaceName: The string name of the interface, e.g. eth0 <Returns> A list of IP addresses associated with the interface. """ # Launch up a shell, get the feed back # We use ifconfig with the interface name. ifconfig_process = portable_popen.Popen( ["/sbin/ifconfig", interfaceName.strip()]) ifconfig_output, _ = ifconfig_process.communicate() ifconfig_lines = textops.textops_rawtexttolines(ifconfig_output) # Look for ipv4 addresses target_lines = textops.textops_grep("inet", ifconfig_lines) # and not ipv6 target_lines = textops.textops_grep("inet6", target_lines, exclude=True) # Only take the ip(s) target_lines = textops.textops_cut(target_lines, delimiter=":", fields=[1]) target_lines = textops.textops_cut(target_lines, delimiter=" ", fields=[0]) # Create an array for the ip's ipaddressList = [] for line in target_lines: # Strip the newline and any spacing line = line.strip("\n\t ") ipaddressList.append(line) # Done, return the interfaces return ipaddressList
def _fetch_ipconfig_infomation(): """ <Purpose> Fetch's the information from ipconfig and stores it in a useful format. <Returns> A dictionary object. """ # Launch up a shell, get the feedback process = portable_popen.Popen(["ipconfig", "/all"]) # Get the output outputdata = process.stdout.readlines() # Close the pipe process.stdout.close() # Stores the info info_dict = {} # Store the current container current_container = None # Process each line for line in outputdata: # Strip unwanted characters line = line.strip("\r\n") # Check if this line is blank, skip it if line.strip() == "": continue # This is a top-level line if it does not start with a space if not line.startswith(" "): # Do some cleanup line = line.strip(" :") # Check if this exists in the top return dictionary, if not add it if line not in info_dict: info_dict[line] = {} # Set the current container current_container = line # Otherwise, this line just contains some information else: # Check if we are in a container if not current_container: continue # Cleanup line = line.strip() line = line.replace(". ", "") # Explode on the colon (key, value) = line.split(":", 1) # More cleanup key = key.strip() value = value.strip() # Store this info_dict[current_container][key] = value # Return everything return info_dict
program_name = "noop_program_for_repy_callarg_test.r2py" try: os.remove(program_name) except OSError: # The file wasn't there. No problem. pass noop_prog = open(program_name, "w") noop_prog.close() # Call Repy. If repy.py mistakingly consumes the --logfile arg, it # will create a file named logfile_prefix + ".old" (or .new if .old # already existed). logfile_prefix = "REPY_CALLARG_TEST" repy_process = portable_popen.Popen([ sys.executable, "repy.py", "restrictions.default", program_name, "--logfile", logfile_prefix ]) # Give things time to settle (launching of subprocess, code safety check, etc.) time.sleep(5) # See if the logfile was created. for filename in os.listdir("."): if filename.startswith(logfile_prefix): print "Found file", filename, "which indicates that repy.py consumed " print "the argument meant for the sandboxed program. Bad." break # Finally, remove any files we might created for filename in [ program_name, logfile_prefix + ".old", logfile_prefix + ".new"
def startvessel_ex(vesselname, prog_platform, argstring): # Convert the programming platform to lowercase to make # it case insensitive. prog_platform = prog_platform.lower() if vesselname not in vesseldict: raise BadRequest, "No such vessel" if vesseldict[vesselname]['status'] == 'Started': raise BadRequest("Vessel has already been started") if prog_platform not in prog_platform_dir.keys(): raise BadRequest("Programming language platform is not supported.") # remove any prior stop file so that we can start if os.path.exists(vesseldict[vesselname]['stopfilename']): os.remove(vesseldict[vesselname]['stopfilename']) for char in argstring: if char not in allowedchars: raise BadRequest("Character '" + char + "' not allowed in arguments") # I'm going to capture the status and timestamp and then check the see if # the timestamp is updated... oldstatus, oldtimestamp = statusstorage.read_status( vesseldict[vesselname]['statusfilename']) # Armon: this is required to fetch the networkrestrictions information from the configuration configuration = persist.restore_object("nodeman.cfg") # Armon: Generate the IP/Iface preferences if they exist ip_iface_preference_flags = [] ip_iface_preference_str = "" # Needed for Win Mobile # Only add the flags if everything necessary exists if 'networkrestrictions' in configuration and 'repy_restricted' in configuration['networkrestrictions'] \ and configuration['networkrestrictions']['repy_restricted'] and 'repy_user_preference' in configuration['networkrestrictions']: # Generate the preference list for (is_ip, value ) in configuration['networkrestrictions']['repy_user_preference']: # Append the correct flag if is_ip: ip_iface_preference_flags.append("--ip") ip_iface_preference_str += "--ip " else: ip_iface_preference_flags.append("--iface") ip_iface_preference_str += "--iface " # Append the value ip_iface_preference_flags.append(value) ip_iface_preference_str += "'" + value + "' " # Check for the --nootherips flag if 'repy_nootherips' in configuration[ 'networkrestrictions'] and configuration[ 'networkrestrictions']['repy_nootherips']: # Append the flag ip_iface_preference_flags.append("--nootherips") ip_iface_preference_str += "--nootherips " # Find the location where the sandbox files is located. Location of repyV1, repyV2 etc. prog_platform_location = os.path.join(prog_platform_dir[prog_platform], "repy.py") # I use absolute paths so that repy can still find the files after it # changes directories... # Conrad: switched this to sequence-style Popen invocation so that spaces # in files work. Switched it back to absolute paths. command = [ sys.executable, prog_platform_location ] + ip_iface_preference_flags + [ "--logfile", os.path.abspath(vesseldict[vesselname]['logfilename']), "--stop", os.path.abspath(vesseldict[vesselname]['stopfilename']), "--status", os.path.abspath(vesseldict[vesselname]['statusfilename']), "--cwd", os.path.abspath(vesselname), "--servicelog", "--execinfo", os.path.abspath(vesseldict[vesselname]['resourcefilename']) ] + argstring.split() portable_popen.Popen(command) starttime = nonportable.getruntime() # wait for 10 seconds for it to start (else return an error) while nonportable.getruntime() - starttime < 10: newstatus, newtimestamp = statusstorage.read_status( vesseldict[vesselname]['statusfilename']) # Great! The timestamp was updated... The new status is the result of # our work. Let's tell the user what happened... if newtimestamp != oldtimestamp and newstatus != None: break # sleep while busy waiting... time.sleep(.5) else: return "Did not start in a timely manner\nWarning" # We need to update the status in the table because the status thread might # not notice this before our next request... (else occasional failures on XP) nmstatusmonitor.update_status(vesseldict, vesselname, newstatus, newtimestamp) return newstatus + "\nSuccess"