Esempio n. 1
0
def Main():
    cgiEnv = lib_common.CgiEnv()
    pidProc = int(cgiEnv.GetId())

    grph = cgiEnv.GetGraph()

    node_process = lib_common.gUriGen.PidUri(pidProc)
    proc_obj = CIM_Process.PsutilGetProcObj(pidProc)

    # Now we are parsing the command line.
    cmd_line = CIM_Process.PsutilProcToCmdline(proc_obj)

    sys.stderr.write("cmd_line=%s\n" % str(cmd_line))

    # Similar to split, but ignores white spaces in double quotes.
    argvArray = re.findall(r'(?:[^\s "]|"(?:\\.|[^"])*")+', cmd_line)

    sys.stderr.write("argvArray=%s\n" % str(argvArray))

    # This extracts the command file name and creates a node for it.
    for theArg in argvArray[1:]:
        if theArg[0] == "/":
            continue

        # Check if the file exists in the current directory.
        currPwd, errMsg = CIM_Process.PsutilProcCwd(proc_obj)
        if not currPwd:
            sys.stderr.write("PyFilNode: %s\n" % errMsg)
            break

        allDirsToSearch = [currPwd]

        envPath = CIM_Process.GetEnvVarProcess("PATH", proc_obj.pid)
        if envPath:
            allDirsToSearch += envPath.split(";")

        # Now tries all possible dirs, starting with current directory.
        for aDir in allDirsToSearch:
            fullScriptPath = os.path.join(aDir, theArg)
            if os.path.isfile(fullScriptPath):
                sys.stderr.write("fullScriptPath=%s\n" % fullScriptPath)
                scriptNode = lib_common.gUriGen.FileUri(fullScriptPath)
                grph.add((node_process, pc.property_runs, scriptNode))
                break

        break

    cgiEnv.OutCgiRdf()
Esempio n. 2
0
def Usable(entity_type, entity_ids_arr):
    """Python processes only"""

    pid_proc = entity_ids_arr[0]
    try:
        # Any error, no display.
        proc_obj = psutil.Process(int(pid_proc))
    except:
        return False

    cmd_line = CIM_Process.PsutilProcToCmdline(proc_obj)

    cmdlin_split = cmd_line.split(" ")
    exec_nam = cmdlin_split[0]
    bas_nam = os.path.basename(exec_nam)

    # This is a python process because of the executable.
    return bas_nam.startswith("python")
Esempio n. 3
0
def MakeProcDictWindows():
    procDict = dict()

    for proc in psutil.process_iter():
        procName = CIM_Process.PsutilProcToName(proc)
        # procName = proc.name

        # OK pour le process creer par httpd, sous Windows.
        # C:\Python\3.2.3-0.3\pythonw.exe -u D:/Projects/Divers/Reverse/PythonStyle/survol/task_control.py
        #if procName != "pythonw.exe":
        #	continue

        # Might be different depending on the Python interpreter.
        if procName != "python.exe":
            continue

        # With a real subtask:
        # python.exe	18980	24656	C:\Python\3.2.3-0.3\python.exe	C:\Python\3.2.3-0.3\python.exe -c from multiprocessing.forking import main; main() --multiprocessing-fork 788
        # python.exe	24656	14680	C:\Python\3.2.3-0.3\python.exe	python D:/Projects/Divers/Reverse/PythonStyle/survol/sources_top/psutil_processes_perf.py run

        procCmd = CIM_Process.PsutilProcToCmdline(proc)

        pid = proc.pid
        parent_pid = CIM_Process.PsutilProcToPPid(proc)

        # This differentiates between the feeder and the sub-server.
        # This test but get better, but it is OK for the moment.
        mtch_task = re.match(".*/survol/(.*) run", procCmd)
        if mtch_task:
            subDct = {'parentPid': parent_pid, 'script': mtch_task.group(1)}
            try:
                procDict[pid].update(subDct.items())
            except KeyError:
                procDict[pid] = subDct
            continue

        if re.match(".*multiprocessing.forking.*", procCmd):
            subDct = {'subPid': pid, 'subScript': procCmd}
            try:
                procDict[parent_pid].update(subDct.items())
            except KeyError:
                procDict[parent_pid] = subDct
            continue
    return procDict
Esempio n. 4
0
def MakeProcDictLinux():
    procDict = dict()

    for proc in psutil.process_iter():

        procName = proc.name

        # BEWARE: It depends on the interpreter.
        if procName != "python":
            continue

        # With a real subtask:
        # apache    8423     1  0 12:36 ?        00:00:00 python /home/rchateau/public_html/RevPython/survol/sources_top/tcpdump.py run
        # apache    8426  8423  0 12:36 ?        00:00:00 python /home/rchateau/public_html/RevPython/survol/sources_top/tcpdump.py run

        procCmd = CIM_Process.PsutilProcToCmdline(proc)

        pid = proc.pid
        parent_pid = CIM_Process.PsutilProcToPPid(proc)

        # This differentiates between the feeder and the sub-server.
        # This test but get better, but it is OK for the moment.
        mtch_task = re.match(".*/survol/(.*) run", procCmd)
        if mtch_task:
            if parent_pid == 1:
                subDct = {
                    'parentPid': parent_pid,
                    'script': mtch_task.group(1)
                }
                try:
                    procDict[pid].update(subDct.items())
                except KeyError:
                    procDict[pid] = subDct
            else:
                subDct = {'subPid': pid, 'subScript': procCmd}
                try:
                    procDict[parent_pid].update(subDct.items())
                except KeyError:
                    procDict[parent_pid] = subDct
            continue
    return procDict
Esempio n. 5
0
def Main():
    cgiEnv = lib_common.CgiEnv()
    pidProc = int(cgiEnv.GetId())

    grph = cgiEnv.GetGraph()

    node_process = lib_common.gUriGen.PidUri(pidProc)
    proc_obj = CIM_Process.PsutilGetProcObj(int(pidProc))

    # Now we are parsing the command line.
    cmd_line = CIM_Process.PsutilProcToCmdline(proc_obj)

    sys.stderr.write("cmd_line=%s\n" % str(cmd_line))

    # Similar to split, but ignores white spaces in double quotes.
    argvArray = re.findall(r'(?:[^\s "]|"(?:\\.|[^"])*")+', cmd_line)

    sys.stderr.write("argvArray=%s\n" % str(argvArray))

    argvArgs = " ".join(argvArray[1:])

    sys.stderr.write("argvArgs=%s\n" % argvArgs)

    opts, otherArgs = getopt.getopt(argvArgs, "Bc:dEhim:ORQ:sStuvVW:x3")

    ignoreEnvs = False
    for opt, arg in opts:
        if opt == '-E':
            ignoreEnvs = True

    if otherArgs:
        filNam = otherArgs
        filNode = PyFilNode(proc_obj, filNam, ignoreEnvs)
        if filNode:
            grph.add((node_process, pc.property_runs, filNode))

        sys.stderr.write("filNam=%s\n" % filNam)

    cgiEnv.OutCgiRdf()
Esempio n. 6
0
def Main():
    paramkey_hide_user_accounts = "Hide user accounts"
    paramkey_show_command_line = "Show command line"

    cgiEnv = lib_common.ScriptEnvironment(parameters={
        paramkey_hide_user_accounts: False,
        paramkey_show_command_line: False
    })

    flag_hide_user_accounts = bool(
        cgiEnv.get_parameters(paramkey_hide_user_accounts))
    flag_show_command_line = bool(
        cgiEnv.get_parameters(paramkey_show_command_line))

    grph = cgiEnv.GetGraph()

    # With a dictionary so node are created once only.
    # This attribute belongs to the function (defintion), and not to the function call.
    # Must be mindful of threading and recursion.

    Main.dict__pid_to_node = {}

    def _pid_to_node(the_pid):
        try:
            return Main.dict__pid_to_node[the_pid]
        except KeyError:
            node = lib_uris.gUriGen.PidUri(the_pid)
            Main.dict__pid_to_node[the_pid] = node
            return node

    # Problem here: There is a second loopkup to get the name of the process.
    # In the mean time, the process might have disappeared.
    # Another problem due to Windows is that a parent process might have exit,
    # although it children processes are not reassigned (As it is the case on Unix).
    # This is a "non-existent process".
    for proc in psutil.process_iter():
        pid = proc.pid
        parent_pid = proc.ppid()

        # Built the same way in other RDF documents.
        node_process = _pid_to_node(pid)
        parent_node_process = _pid_to_node(parent_pid)

        # We avoid duplicating the edges. Why would the RDF merge do?
        grph.add((node_process, pc.property_ppid, parent_node_process))
        grph.add((node_process, pc.property_pid, lib_util.NodeLiteral(pid)))

        if not flag_hide_user_accounts:
            usr_nam = CIM_Process.PsutilProcToUser(proc, None)
            if usr_nam:
                # TODO: Maybe it would be more convenient to display the user as a simple string,
                # TODO: such as lib_util.NodeLiteral(usr_nam)
                user_node = lib_uris.gUriGen.UserUri(usr_nam)
                grph.add((node_process, pc.property_user, user_node))

        if flag_show_command_line:
            cmd_line = CIM_Process.PsutilProcToCmdline(proc)
            if cmd_line and cmd_line != CIM_Process.ProcessAccessDenied:
                # TODO: The command line should be clickable.
                # TODO: ... but just display it as a string.
                # TODO: See CIM_Process.add_command_line_arguments
                node_cmd_line = lib_util.NodeLiteral(cmd_line)
                grph.add((node_process, pc.property_command, node_cmd_line))

        # TODO: Add the username as a property ? Change the color with the username ?
        # TODO: Get icons of users or programs, use their colors ?
        # TODO: Or get the graphic chart of any software related to a resource ?

    # TODO: It would be neat when displaying in SVG,
    # TODO: ... to specify that some nodes, when used as objects (not subjects),
    # TODO: ... should not have their own node but simply appear as an URL in the box of the subject.
    # TODO: This would simplify the network.
    # TODO: It would still be possible to display the object node, but without the connections.
    # TODO: Something like: isolated_classes=["LMI_Account"]
    # TODO: This could be a tunable parameter.
    cgiEnv.OutCgiRdf()