Example #1
0
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)
Example #2
0
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
Example #3
0
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)
Example #4
0
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)
Example #5
0
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
Example #6
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:
        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)
Example #7
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)
Example #8
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
Example #9
0
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
Example #10
0
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
Example #11
0
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"
Example #12
0
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"