refs #1093 initial version of InventorySoftware, pending to fix log functionality

pull/1/head
Antonio Guerrero 2024-11-05 05:45:25 +00:00
parent 844ae53c05
commit 269fcd288d
3 changed files with 230 additions and 61 deletions

View File

@ -7,13 +7,13 @@ import sys
def main(arg1, arg2, dest_file):
start_time = time.time()
# Load the engine configurator from the engine.cfg file
# Cargar la configuración del motor desde el archivo engine.cfg
og_engine_configurate = os.getenv('OGENGINECONFIGURATE')
if not og_engine_configurate:
with open('/opt/opengnsys/etc/engine.cfg') as f:
exec(f.read())
# Clear the temporary files used as log tracking for httpdlog
# Limpiar los archivos temporales usados como log para httpdlog
og_log_session = os.getenv('OGLOGSESSION')
og_log_command = os.getenv('OGLOGCOMMAND')
if og_log_session and og_log_command:
@ -24,24 +24,33 @@ def main(arg1, arg2, dest_file):
with open(f"{og_log_command}.tmp", 'w') as f:
f.write(" ")
# Log the start of execution
# Registrar el inicio de ejecución
msg_interface_start = os.getenv('MSG_INTERFACE_START')
if msg_interface_start:
subprocess.run(['ogEcho', 'log', 'session', f"{msg_interface_start} {__file__} {arg1} {arg2}"])
# Get the software info file and copy it to the destination
# Call the actual listSoftwareInfo function
file = listSoftwareInfo(arg1, arg2)
# Ejecutar el script listSoftwareInfo y capturar el archivo de salida
try:
result = subprocess.run(
["python3", "/opt/opengnsys/scripts/listSoftwareInfo.py", arg1, arg2],
capture_output=True,
text=True,
check=True
)
file = result.stdout.strip() # Captura la salida del script
except subprocess.CalledProcessError as e:
print(f"Error al ejecutar listSoftwareInfo: {e.stderr}")
sys.exit(e.returncode)
# Copiar el archivo resultante a dest_file
shutil.copy(file, dest_file)
# Log the execution time
# Registrar el tiempo de ejecución
elapsed_time = time.time() - start_time
msg_scripts_time_partial = os.getenv('MSG_SCRIPTS_TIME_PARTIAL')
if msg_scripts_time_partial:
subprocess.run(['ogEcho', 'log', 'session', f" [ ] {msg_scripts_time_partial} : {int(elapsed_time // 60)}m {int(elapsed_time % 60)}s"])
if __name__ == "__main__":
if len(sys.argv) != 4:
print("Usage: python InventarioSoftware.py <arg1> <arg2> <dest_file>")

View File

@ -0,0 +1,179 @@
import subprocess
import os
import re
#from engine.FileLib import *
#from engine.SystemLib import *
def chntpw(*args):
chntpw_path = subprocess.check_output(['which', 'drbl-chntpw']).decode().strip()
if not chntpw_path:
chntpw_path = subprocess.check_output(['which', 'chntpw']).decode().strip()
subprocess.run([chntpw_path, '-e'] + list(args), timeout=5)
def ogAddRegistryKey(path_mountpoint, str_hive, str_key):
# Variables locales.
FILE = ogGetHivePath(path_mountpoint, str_hive)
if not FILE:
return
# Añadir nueva clave.
chntpw(FILE, 'cd', str_key.rsplit('\\', 1)[0])
chntpw(FILE, 'nk', str_key.rsplit('\\', 1)[-1])
chntpw(FILE, 'q')
chntpw(FILE, 'y')
def ogAddRegistryValue(path_mountpoint, str_hive, str_key, str_valuename, str_valuetype=''):
# Variables locales.
FILE = ogGetHivePath(path_mountpoint, str_hive)
if not FILE:
return
# Determine the value type.
if str_valuetype.upper() == 'STRING' or str_valuetype == '':
TYPE = 1
elif str_valuetype.upper() == 'BINARY':
TYPE = 3
elif str_valuetype.upper() == 'DWORD':
TYPE = 4
else:
ogRaiseError(OG_ERR_OUTOFLIMIT, str_valuetype)
return
# Add the registry value.
chntpw(FILE, 'cd', str_key.rsplit('\\', 1)[0])
chntpw(FILE, 'nv', str_valuename.rsplit('\\', 1)[-1], TYPE)
chntpw(FILE, 'q')
chntpw(FILE, 'y')
def ogDeleteRegistryKey(path_mountpoint, str_hive, str_key):
# Variables locales.
FILE = ogGetHivePath(path_mountpoint, str_hive)
if not FILE:
return
# Delete the registry key.
subprocess.run(['chntpw', FILE], input=f"cd {str_key.rsplit('\\', 1)[0]}\ndk {str_key.rsplit('\\', 1)[-1]}\nq\ny\n".encode(), timeout=5)
def ogDeleteRegistryValue(path_mountpoint, str_hive, str_valuename):
# Variables locales.
FILE = ogGetHivePath(path_mountpoint, str_hive)
if not FILE:
return
# Delete the registry value.
chntpw(FILE, 'cd', str_valuename.rsplit('\\', 1)[0])
chntpw(FILE, 'dv', str_valuename.rsplit('\\', 1)[-1])
chntpw(FILE, 'q')
chntpw(FILE, 'y')
def ogGetHivePath(path_mountpoint, str_hive):
# Variables locales.
FILE = None
# Camino del fichero de registro de usuario o de sistema (de menor a mayor prioridad).
FILE = ogGetPath(f"/{path_mountpoint}/Windows/System32/config/{str_hive}")
if not FILE:
FILE = ogGetPath(f"/{path_mountpoint}/Users/{str_hive}/NTUSER.DAT")
if not FILE:
FILE = ogGetPath(f"/{path_mountpoint}/winnt/system32/config/{str_hive}")
if not FILE:
FILE = ogGetPath(f"/{path_mountpoint}/Documents and Settings/{str_hive}/NTUSER.DAT")
if FILE and os.path.isfile(FILE):
return FILE
else:
ogRaiseError(OG_ERR_NOTFOUND, f"{path_mountpoint} {str_hive}")
return None
def ogGetRegistryValue(path_mountpoint, str_hive, str_valuename):
# Variables locales.
FILE = ogGetHivePath(path_mountpoint, str_hive)
if not FILE:
return
# Devolver el dato del valor de registro.
chntpw_cmd = f'''
chntpw "{FILE}" << EOT 2> /dev/null | awk '/> Value/ {{
if (index($0, "REG_BINARY") > 0) {{
data=""
}} else {{
getline
data=$0
}}
}}
/^:[0-9A-F]+ / {{
data=data""substr($0, 9, 48)
}}
END {{
print data
}}'
cd {str_valuename.rsplit('\\', 1)[0]}
cat {str_valuename.rsplit('\\', 1)[-1]}
q
EOT
'''
subprocess.run(chntpw_cmd, shell=True, timeout=5)
def ogListRegistryKeys(path_mountpoint, str_hive, str_key):
# Variables locales.
FILE = ogGetHivePath(path_mountpoint, str_hive)
if not FILE:
return
# Devolver la lista de claves de registro.
chntpw_cmd = f'''
chntpw "{FILE}" << EOT 2> /dev/null | awk 'BEGIN {{FS="[<>]"}} $1~/^ $/ {{print $2}}'
ls {str_key}
q
EOT
'''
subprocess.run(chntpw_cmd, shell=True, timeout=5)
def ogListRegistryValues(path_mountpoint, str_hive, str_key):
# Variables locales.
FILE = ogGetHivePath(path_mountpoint, str_hive)
if not FILE:
return
# Devolver la lista de valores de registro.
chntpw_cmd = f'''
chntpw "{FILE}" << EOT 2> /dev/null | awk 'BEGIN {{FS="[<>]"}} $1~/REG_/ {{print $2}}'
ls {str_key}
q
EOT
'''
subprocess.run(chntpw_cmd, shell=True, timeout=5)
def ogSetRegistryValue(path_mountpoint, str_hive, str_valuename, str_data):
# Variables locales.
FILE = ogGetHivePath(path_mountpoint, str_hive)
if not FILE:
return
# Fichero temporal para componer la entrada al comando "chntpw".
tmpfile = "/tmp/chntpw$$"
try:
# Comprobar tipo de datos del valor del registro.
with open(tmpfile, 'w') as f:
f.write(f"ls {str_valuename.rsplit('\\', 1)[0]}\nq\n")
output = subprocess.check_output(['chntpw', FILE], input=open(tmpfile, 'rb'), stderr=subprocess.DEVNULL).decode()
if f"BINARY.*<{str_valuename.rsplit('\\', 1)[-1]}>" in output:
# Procesar tipo binario (incluir nº de bytes y líneas de 16 parejas hexadecimales).
if not re.match(r'^([0-9A-F]{2} )*$', str_data):
ogRaiseError(OG_ERR_FORMAT, f'"{str_data}"')
return
n = len(str_data) + 1
with open(tmpfile, 'w') as f:
f.write(f"cd {str_valuename.rsplit('\\', 1)[0]}\ned {str_valuename.rsplit('\\', 1)[-1]}\n{int(n/3)}\n")
for i in range(0, n, 48):
f.write(f":{i//3:05x} {str_data[i:i+48]}\n")
f.write("s\nq\ny\n")
else:
# Cambiar el dato del valor de registro para cadenas y bytes.
with open(tmpfile, 'w') as f:
f.write(f"cd {str_valuename.rsplit('\\', 1)[0]}\ned {str_valuename.rsplit('\\', 1)[-1]}\n{str_data}\nq\ny\n")
# Aplicar cambios.
subprocess.run(['chntpw', FILE], input=open(tmpfile, 'rb'), stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
finally:
os.remove(tmpfile)

View File

@ -1,56 +1,37 @@
import sys
import os
import re
import subprocess
sys.path.append('/opt/opengnsys/lib/engine/bin')
from NetLib import ogGetIpAddress
from SystemLib import ogRaiseError
from InventoryLib import ogListSoftware
#!/usr/bin/env python3
def main():
PROG = os.path.basename(__file__)
REDUCED = "no"
REDUCED = False
if len(sys.argv) > 1 and sys.argv[1] == "-r":
REDUCED = "yes"
REDUCED = True
sys.argv.pop(1)
if len(sys.argv) != 3:
og_raise_error(1, f"Usage: {PROG} [-r] ndisk npart")
og_raise_error("OG_ERR_FORMAT", "Usage: listSoftwareInfo [-r] disk partition")
sys.exit(1)
ndisk = sys.argv[1]
npart = sys.argv[2]
disk = sys.argv[1]
partition = sys.argv[2]
OGLOG = "/path/to/log" # Replace with actual log path
SERVERLOGDIR = None
# Directorio del servidor donde se exportan los ficheros de registro
server_log_dir = "/mnt/oglog" # Assuming OGLOG is mounted at /mnt/oglog
# Simulate the mount command and awk processing
mounts = subprocess.check_output(['mount']).decode('utf-8')
for line in mounts.splitlines():
parts = line.split()
if len(parts) > 3 and parts[2] == OGLOG:
SERVERLOGDIR = parts[1]
break
# Fichero de listado: soft-IP-disk-partition
soft_file = f"soft-{ogGetIpAddress()}-{disk}-{partition}"
log_path = os.path.join(server_log_dir, soft_file)
if SERVERLOGDIR is None:
og_raise_error(1, "Could not determine server log directory")
SOFTFILE = f"soft-{og_get_ip_address()}-{ndisk}-{npart}"
softfile_path = os.path.join(OGLOG, SOFTFILE)
try:
if REDUCED == "no":
software_list = og_list_software(ndisk, npart)
# Redirigir salida al fichero de listado
with open(log_path, "w") as log_file:
if not REDUCED:
ogListSoftware(disk, partition, log_file)
else:
software_list = "\n".join(
line for line in og_list_software(ndisk, npart).splitlines()
if not re.search(r"\(KB[0-9]{6}\)", line)
)
for line in og_list_software(disk, partition):
if "(KB" not in line:
log_file.write(line + "\n")
with open(softfile_path, 'w') as f:
f.write(software_list)
except Exception as e:
og_raise_error(1, str(e))
print(softfile_path)
if __name__ == "__main__":
main()
print(log_path)