def tree_parent_process(grph, proc_obj): try: the_pid = proc_obj.pid if the_pid == 0 or the_pid == 1: return # Strange, but apparently it can happen. the_ppid = CIM_Process.PsutilProcToPPid(proc_obj) if the_ppid == 0: return if lib_common.UselessProc(proc_obj): return node_process = lib_common.gUriGen.PidUri(the_pid) node_pprocess = lib_common.gUriGen.PidUri(the_ppid) grph.add((node_pprocess, pc.property_ppid, node_process)) CIM_Process.AddInfo(grph, node_pprocess, [str(the_ppid)]) AddExtraInformationtoProcess(grph, node_process, proc_obj) parent_proc_obj = CIM_Process.PsutilGetProcObjNoThrow(int(the_ppid)) tree_parent_process(grph, parent_proc_obj) # This exception depends on the version of psutil. except CIM_Process.NoSuchProcess: # Maybe a process has suddenly disappeared. It does not matter. return
def FunctionProcess(mapToProc, proc): # The process might have left in the meantime. pid = proc.pid if lib_common.UselessProc(proc): return try: all_maps = CIM_Process.PsutilProcMemmaps(proc) except: exc = sys.exc_info()[1] sys.stderr.write("get_memory_maps Pid=%d. Caught %s\n" % (pid, str(exc))) return # This takes into account only maps accessed by several processes. # TODO: What about files on a shared drive? # To make things simple, for the moment mapped memory is processed like files. # sys.stderr.write("NbMaps=%d\n" % len(all_maps) ) for map in all_maps: cleanPath = GoodMap(map.path) if cleanPath == "": continue # sys.stderr.write( "Adding cleanPath=%s\n" % cleanPath ) try: theList = mapToProc[cleanPath] theList.append(pid) except KeyError: mapToProc[cleanPath] = [pid]
def Main(): paramkeyShowUnconnected = "Show unconnected sockets" # TODO: At the moment, only uses false default values for boolean parameters, # TODO: because CGI and the CGI lib do not send empty strings. cgiEnv = lib_common.CgiEnv(parameters={paramkeyShowUnconnected: False}) flagShowUnconnected = bool(cgiEnv.GetParameters(paramkeyShowUnconnected)) grph = cgiEnv.GetGraph() for proc in CIM_Process.ProcessIter(): try: if lib_common.UselessProc(proc): continue pid = proc.pid # TCP sockets only. all_connect = CIM_Process.PsutilProcConnections(proc) if all_connect: node_process = lib_common.gUriGen.PidUri(pid) # Trop lourd, ca ne sert a rien, dans la mesure ou les processes # ont le meme URI, donc ils DOIVENT etre fusionnes (A verifier). # A la limite, ca pourrait etre un attribut. # grph.add( ( node_process, pc.property_pid, Literal(pid) ) ) # Not sure this is the best plmace to add this edge. grph.add( (node_process, pc.property_host, lib_common.nodeMachine)) grph.add((node_process, pc.property_pid, lib_common.NodeLiteral(pid))) # Les deux fonctionnent sous Linux mais verifier sous Windows. # Un peu plus lent en asynchrone si peu de sockets; # Ou il faudrait un parametre. # lib_common.PsutilAddSocketToGraph(node_process,all_connect,grph) # lib_common.PsutilAddSocketToGraphAsync(node_process,all_connect,grph,flagShowUnconnected) # TODO: MAYBE CREATES ALL THE PROCESSES AND RUN THE THREADS ON THE COMPLETE LIST ??? survol_addr.PsutilAddSocketToGraphAsync( node_process, all_connect, grph, flagShowUnconnected) except psutil.AccessDenied: pass except psutil.NoSuchProcess: pass except: exc = sys.exc_info()[1] lib_common.ErrorMessageHtml("Caught:" + str(exc)) raise cgiEnv.OutCgiRdf("LAYOUT_SPLINE")
def tree_subprocesses(grph, proc_obj): if lib_common.UselessProc(proc_obj): return node_process = lib_common.gUriGen.PidUri(proc_obj.pid) try: # Old versions of psutil subprocs = proc_obj.get_children(recursive=False) except Exception: # From psutil 3.2.2 at least. subprocs = proc_obj.children(recursive=False) for child in subprocs: node_child = lib_common.gUriGen.PidUri(child.pid) grph.add((node_process, pc.property_ppid, node_child)) AddExtraInformationtoProcess(grph, node_child, child) tree_subprocesses(grph, child)
def Main(): paramkeyShowSharedLib = "Show shared libraries" paramkeyShowFontFiles = "Show font files" paramkeyShowNonShared = "Show non shared files" # TODO: At the moment, only uses false default values for boolean parameters, # TODO: because CGI and the CGI lib do not send empty strings. cgiEnv = lib_common.CgiEnv( parameters={ paramkeyShowSharedLib: False, paramkeyShowFontFiles: False, paramkeyShowNonShared: False }) flagShowSharedLib = bool(cgiEnv.GetParameters(paramkeyShowSharedLib)) flagShowFontFiles = bool(cgiEnv.GetParameters(paramkeyShowFontFiles)) flagShowNonShared = bool(cgiEnv.GetParameters(paramkeyShowNonShared)) grph = cgiEnv.GetGraph() ################################################################################ Main.dictPathToNod = {} AddPidFileLink.dictFiles = {} # Maybe this is done in another CGI. What happens when merging ? grph.add((lib_common.nodeMachine, pc.property_hostname, lib_common.NodeLiteral(lib_util.currentHostname))) # https://code.google.com/p/psutil/issues/detail?id=340 # This might hang. for proc in CIM_Process.ProcessIter(): try: if lib_common.UselessProc(proc): continue pid = proc.pid node_process = None # http://code.google.com/p/psutil/issues/detail?id=340 # https://github.com/giampaolo/psutil/issues/340 for fil in CIM_Process.PsutilProcOpenFiles(proc): # Some files are not interesting even if accessed by many processes. if lib_common.MeaninglessFile(fil.path, not flagShowSharedLib, not flagShowFontFiles): continue # Adds the process node only if it has at least one open file. if node_process == None: node_process = lib_common.gUriGen.PidUri(pid) grph.add((node_process, pc.property_pid, lib_common.NodeLiteral(pid))) # TODO: What about files on a shared drive? if flagShowNonShared: fileNode = PathToNod(fil.path) grph.add((node_process, pc.property_open_file, fileNode)) else: # This takes into account only files accessed by several processes. AddPidFileLink(grph, node_process, fil.path) # except psutil.AccessDenied: # pass except: exc = sys.exc_info()[1] sys.stderr.write("Exception:%s\n" % str(exc)) pass cgiEnv.OutCgiRdf("LAYOUT_SPLINE")
def Main(): cgiEnv = lib_common.CgiEnv() 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.dictPidToNode = {} def PidToNode(pid): global dictPidToNode try: return Main.dictPidToNode[pid] except KeyError: node = lib_common.gUriGen.PidUri(pid) Main.dictPidToNode[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 CIM_Process.ProcessIter(): if lib_common.UselessProc(proc): continue # proc=['__class__', '__delattr__', '__dict__', '__doc__', '__eq__', '__format__', '__getattribute__', '__hash__', '__init__', '__modu # le__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', ' # __weakref__', '_create_time', '_exe', '_gone', '_hash', '_ident', '_init', '_last_proc_cpu_times', '_last_sys_cpu_times', '_name', ' # _pid', '_ppid', '_proc', 'as_dict', 'children', 'cmdline', 'connections', 'cpu_affinity', 'cpu_percent', 'cpu_times', 'create_time', # 'cwd', 'exe', 'io_counters', 'ionice', 'is_running', 'kill', 'memory_info', 'memory_info_ex', 'memory_maps', 'memory_percent', 'nam # e', 'nice', 'num_ctx_switches', 'num_handles', 'num_threads', 'open_files', 'parent', 'pid', 'ppid', 'resume', 'send_signal', 'statu # s', 'suspend', 'terminate', 'threads', 'username', 'wait']' # sys.stderr.write("proc=%s\n"%str(dir(proc))) procName = CIM_Process.PsutilProcToName(proc) pid = proc.pid parent_pid = CIM_Process.PsutilProcToPPid(proc) # Built the same way in other RDF documents. node_process = PidToNode(pid) parent_node_process = PidToNode(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_common.NodeLiteral(pid))) usrNam = CIM_Process.PsutilProcToUser(proc, None) if usrNam: grph.add((node_process, pc.property_user, lib_common.NodeLiteral(usrNam))) # TODO: Add the username as a property ? Change the color with the username ? # Pour les couleurs, on pourrait imaginer d'aller chercher les icones des utilisateurs # ou des programmes et d'en prendre la couleur dominante ? # Ou bien, si un objet est associe a un de nos packages, en prendre les attributs graphiques: # Si c'est un process oracle, on prend les couleurs de notre package Oracle etc... # procUsername = lib_common.PsutilProcToUser(proc) # grph.add( ( node_process, pc.property_user, lib_common.NodeLiteral(procUsername) ) ) cgiEnv.OutCgiRdf()
def DisplayMappedProcesses(grph, fileName): grph.add((lib_common.nodeMachine, pc.property_hostname, lib_common.NodeLiteral(lib_util.currentHostname))) # This is also a file mapped into memory. uriMappedFile = lib_common.gUriGen.FileUri(fileName) uriMemMap = None try: statinfo = os.stat(fileName) except Exception: exc = sys.exc_info()[1] grph.add((uriMappedFile, lib_common.MakeProp("Error"), lib_common.NodeLiteral(str(exc)))) return fileSize = lib_util.AddSIUnit(statinfo.st_size, "B") grph.add((uriMappedFile, pc.property_file_size, lib_common.NodeLiteral(fileSize))) propMemoryRSS = lib_common.MakeProp("Resident Set Size") for proc in CIM_Process.ProcessIter(): if lib_common.UselessProc(proc): continue pid = proc.pid try: all_maps = CIM_Process.PsutilProcMemmaps(proc) except: # Probably psutil.AccessDenied exc = sys.exc_info()[1] # sys.stderr.write("get_memory_maps Pid=%d. Caught %s\n" % (pid,str(exc)) ) continue # sys.stderr.write("get_memory_maps OK Pid=%d:%s.\n" % (pid,str(all_maps)) ) for map in all_maps: # This, because all Windows paths are "standardized" by us. cleanMapPath = map.path.replace("\\", "/") # MapPath=C:\Windows\System32\KernelBase.dll fileName=c:\windows\system32\API-MS-WIN-CORE-LOCALIZATION-L1-1-0.DLL # sys.stderr.write("Pid=%d MapPath=%s cleanMapPath=%s fileName=%s\n" % (pid,map.path,cleanMapPath,fileName)) if lib_util.isPlatformWindows: # Horrible conversion due to Windows ... sameFil = map.path.replace("\\", "/").lower() == fileName.replace( "\\", "/").lower() else: sameFil = map.path == fileName if sameFil: sys.stderr.write( "Pid=%d MapPath=%s cleanMapPath=%s fileName=%s\n" % (pid, map.path, cleanMapPath, fileName)) # Maybe this is the first mapping we have found. if uriMemMap == None: uriMemMap = lib_common.gUriGen.MemMapUri(fileName) grph.add((uriMappedFile, pc.property_mapped, uriMemMap)) nodeProcess = lib_common.gUriGen.PidUri(pid) # The property is reversed because of display. grph.add((uriMemMap, pc.property_memmap, nodeProcess)) grph.add((nodeProcess, pc.property_pid, lib_common.NodeLiteral(pid))) # Displays the RSS only if different from the file size. if map.rss != statinfo.st_size: grph.add((nodeProcess, propMemoryRSS, lib_common.NodeLiteral(map.rss)))
def Main(): cgiEnv = lib_common.CgiEnv() userNameWithHost = cgiEnv.GetId() if not lib_util.isPlatformLinux: lib_common.ErrorMessageHtml("Linux only") # Usernames have the syntax user@host # Example: [email protected] userSplit = userNameWithHost.split('@') userName = userSplit[0] # TODO: Should factorize this code. if len(userSplit) > 1: userHost = userSplit[1] if userHost != lib_util.currentHostname: # TODO: Should interrogate other host with "finger" protocol. lib_common.ErrorMessageHtml( "Cannot get user properties on different host:" + userHost) grph = cgiEnv.GetGraph() # It will be possible to transform this into a Json tree by # selecting only the RDF predicate property_ppid. # This will be done in a gui cgi script which takes as input # parameter a CGI script, visible by SLP, stored in a bookmark page # or anything else. # See http://stackoverflow.com/questions/17967686/retrieving-specific-rdf-graph-triples-based-on-predicate-nodes # on how to select triples on a given predicate only. # But in the general case, we cannot know if the RDF graph will be a tree, # something similar to a CSV file (That is, flat) or a general graph. # So we might have to process the resulting graph on the fly, to see # which visualising methods are applicable. # Also, in the case of a tree, we must find ourselves what is its root. for proc in CIM_Process.ProcessIter(): procUsername = CIM_Process.PsutilProcToUser(proc) # sys.stderr.write("procUsername=%s userName=%s\n" % ( procUsername, userName ) ) # procUsername=EURO\\UK936025 userName=UK936025 # procUsername=NT AUTHORITY\\NETWORK SERVICE # procUsername=NT AUTHORITY\\SYSTEM # procUsername=EURO\\UK936025 # procUsername=NT AUTHORITY\\SYSTEM # if procUsername + "@" + lib_util.currentHostname != userName: if procUsername != userName: continue if lib_common.UselessProc(proc): continue procName = proc.name pid = proc.pid parent_pid = CIM_Process.PsutilProcToPPid(proc) # Built the same way in other RDF documents. node_process = lib_common.gUriGen.PidUri(pid) parent_node_process = lib_common.gUriGen.PidUri(parent_pid) # We avoid duplicating the edges. Why would the RFD merge do? grph.add((node_process, pc.property_ppid, parent_node_process)) grph.add((node_process, pc.property_pid, lib_common.NodeLiteral(pid))) # grph.add( ( node_process, pc.property_information, lib_common.NodeLiteral(procUsername) ) ) cgiEnv.OutCgiRdf()
def Main(): cgiEnv = lib_common.CgiEnv() hostname = cgiEnv.GetId() cgiEnv = lib_common.CgiEnv() grph = cgiEnv.GetGraph() hostAddr = lib_util.GlobalGetHostByName(hostname) # hostNode = lib_common.gUriGen.HostnameUri(hostAddr) # BEWARE: The rule whether we use the host name or the host IP is not very clear ! # The IP address would be unambiguous but less clear. hostNode = lib_common.gUriGen.HostnameUri(hostname) # serverBox = lib_common.RemoteBox(hostAddr) # Similar code in "enumerate_sockets.py" for proc in CIM_Process.ProcessIter(): try: if lib_common.UselessProc(proc): continue pid = proc.pid # TCP sockets only. all_connect = CIM_Process.PsutilProcConnections(proc) Main.node_process = None def AssociateWithSockets(grph, larray, rarray): if Main.node_process == None: Main.node_process = lib_common.gUriGen.PidUri(pid) grph.add((Main.node_process, pc.property_host, lib_common.nodeMachine)) grph.add((Main.node_process, pc.property_pid, lib_common.NodeLiteral(pid))) lsocketNode = lib_common.gUriGen.AddrUri(larray[0], larray[1]) grph.add((lsocketNode, pc.property_information, lib_common.NodeLiteral(cnt.status))) rsocketNode = lib_common.gUriGen.AddrUri(rarray[0], rarray[1]) grph.add((lsocketNode, pc.property_information, lib_common.NodeLiteral(cnt.status))) grph.add((lsocketNode, pc.property_socket_end, rsocketNode)) grph.add( (Main.node_process, pc.property_has_socket, rsocketNode)) grph.add((hostNode, pc.property_has_socket, lsocketNode)) for cnt in all_connect: if ((cnt.family == socket.AF_INET) and (cnt.type == socket.SOCK_STREAM) and (cnt.status == 'ESTABLISHED')): (larray, rarray) = survol_addr.SocketToPair(cnt) if hostAddr == larray[0]: AssociateWithSockets(grph, larray, rarray) elif hostAddr == rarray[0]: AssociateWithSockets(grph, rarray, larray) except: pass cgiEnv.OutCgiRdf("LAYOUT_SPLINE")