From 08d8a9510b33109414003feb16f353bf1e6a78d0 Mon Sep 17 00:00:00 2001
From: "gioacchino.vino" <gioacchino.vino@infn.it>
Date: Tue, 26 Sep 2023 18:12:14 +0200
Subject: [PATCH] Added greenbone check

---
 files/greenbone_check.py | 471 ---------------------------------------
 jenkinsfile/Jenkinsfile  |   5 +-
 2 files changed, 3 insertions(+), 473 deletions(-)
 delete mode 100644 files/greenbone_check.py

diff --git a/files/greenbone_check.py b/files/greenbone_check.py
deleted file mode 100644
index 053146e..0000000
--- a/files/greenbone_check.py
+++ /dev/null
@@ -1,471 +0,0 @@
-from gvm.connections import TLSConnection
-from gvm.protocols.gmpv208 import Gmp, AliveTest 
-from gvm.transforms import EtreeTransform
-from gvm.xml import pretty_print
-from time import time, sleep
-import logging
-import json
-import base64
-from sys import argv, exit
-import socket
-import os
-
-def get_version_old():
-	with Gmp(connection, transform=transform) as gmp:
-		gmp.authenticate(auth_name, auth_passwd)	
-		pretty_print(gmp.get_version())
-
-def create_connection():
-    connection_retries = 5
-    retry = connection_retries
-    while(retry > 0):
-        try:
-            gmp = Gmp(connection, transform=transform)
-            gmp.authenticate(auth_name, auth_passwd)
-            return gmp
-        except:
-            print("WARNING: Connection error with the gmp endpoint. Remaining {retry} retries")
-            retry -= 1
-            sleep(0.5)
-    raise Exception("Impossible connect to the gmp endpoint even after 5 retries")
-
-def get_version():
-    gmp = create_connection()
-    res = gmp.get_version()
-    pretty_print(res)
-
-########## PORT LIST ##################################
-
-def create_port_list(port_list_name, ports):
-    gmp = create_connection()
-    res = gmp.create_port_list(port_list_name, ','.join(ports))
-    status = res.xpath('@status')[0]
-    status_text = res.xpath('@status_text')[0]
-    if status == "201":
-        id = res.xpath('@id')[0]
-        return {'name': port_list_name, 'id': id}
-    else:
-        msg = f"ERROR during Port list creation. Status code: {status}, msg: {status_text}"
-        raise Exception(msg) 
-
-def get_port_lists(filter_str="rows=-1"):
-    l_o = []
-    gmp = create_connection()
-    res = gmp.get_port_lists(filter_string=filter_str)
-    for pl in res.xpath('port_list'):
-        o = dict()
-        o['name'] = pl.xpath('name/text()')[0]
-        o['id'] = pl.xpath('@id')[0]
-        o['in_use'] = pl.xpath('in_use/text()')[0]
-        l_o.append(o)
-    return l_o
-
-def delete_port_list(port_list):
-    gmp = create_connection()
-    res = gmp.delete_portlist(port_list['id'])
-    status = res.xpath('@status')[0]
-    status_text = res.xpath('@status_text')[0]
-    if status == "200":
-        print(f"Port_list with id: {port_list['id']} and name: {port_list['name']} DELETED") 
-    else:
-        print(f"ERROR {status}: {status_text}")
-
-def get_or_create_port_list(port_list_name, ports):
-    res = get_port_lists(port_list_name)
-    if len(res) == 0:
-        port_list = create_port_list(port_list_name, ports)
-        return get_port_lists(port_list['id'])[0]
-    elif len(res) == 1:
-        return res[0]
-    else:
-        print(f"WARNING Found {len(res)} results.")
-        return res
-
-############## TARGET  ##################################
-
-def create_target(name,ip,port_list,ovs_ssh_credential):
-    o = dict()
-    gmp = create_connection()
-    res = gmp.create_target(
-            name=name,
-            comment = "",
-            hosts=[ip],
-            port_list_id = port_list['id'],
-            ssh_credential_id = ovs_ssh_credential['id'],
-            alive_test=AliveTest('Consider Alive'))
-    status = res.xpath('@status')[0]
-    status_text = res.xpath('@status_text')[0]
-    if status == "201":
-        id = res.xpath('@id')[0]
-        return {'name': name, 'id': id}
-    else:
-        msg = f"ERROR during Target creation. Status code: {status}, msg: {status_text}"
-        raise Exception(msg) 
-
-def get_targets(filter_str):
-    res = []
-    gmp = create_connection()
-    targets = gmp.get_targets(filter_string=filter_str)
-    for target in targets.xpath('target'):
-        o = dict()
-        o['name'] = target.xpath('name/text()')[0]
-        o['hosts'] = target.xpath('hosts/text()')[0]
-        o['id'] = target.xpath('@id')[0]
-        o['in_use'] = target.xpath('in_use/text()')[0]
-        res.append(o)
-    return res
-
-def delete_target(target):
-    gmp = create_connection()
-    res = gmp.delete_target(target['id'])
-    status = res.xpath('@status')[0]
-    status_text = res.xpath('@status_text')[0]
-    if status == "200":
-        print(f"Port_list with id: {target['id']} and name: {target['name']} DELETED") 
-    else:
-        print(f"ERROR {status}: {status_text}")
-
-def get_or_create_target(target_name,ip,port_list,ovs_ssh_credential):
-    res = get_targets(target_name)
-    if len(res) == 0:
-        t = create_target(target_name,ip,port_list,ovs_ssh_credential)
-        return get_targets(t['id'])[0]
-    elif len(res) == 1:
-        return res[0]
-    else:
-        print(f"Found {len(res)} results. Return None")
-        return res
-
-def search_and_delete_target(target_name):
-    targets = get_targets(target_name)
-    if len(targets) == 1:
-        delete_target(targets[0]['id'])
-    else:
-        raise("Multiple results for search")
-
-def search_and_delete_all_targets(target_name):
-    targets = get_targets(target_name)
-    for target in targets:
-        delete_target(target)
-
-############## TASK ##################################
-
-def create_task(name, config, target, scanner):
-    o = dict()
-    gmp = create_connection()
-    res = gmp.create_task(
-            name=name,
-            config_id=config['id'],
-            target_id=target['id'],
-            scanner_id=scanner['id'])
-    status = res.xpath('@status')[0]
-    status_text = res.xpath('@status_text')[0]
-    if status == "201":
-        id = res.xpath('@id')[0]
-        return {'name': name, 'id': id}
-    else:
-        msg = f"ERROR during Task creation. Status code: {status}, msg: {status_text}"
-        raise Exception(msg)
-
-def get_tasks(filter_str):
-    res = []
-    gmp = create_connection()
-    tasks = gmp.get_tasks(filter_string=filter_str)
-    for task in tasks.xpath('task'):
-            o = dict()
-            o['name'] = task.xpath('name/text()')[0]
-            o['id'] = task.xpath('@id')[0]
-            o['progress'] = task.xpath('progress/text()')[0]
-            o['in_use'] = task.xpath('in_use/text()')[0]
-            o['status'] = task.xpath('status/text()')[0]
-            o['target_id'] = task.xpath('target/@id')[0]
-            try:
-                o['report_id'] = task.xpath('last_report/report/@id')[0]
-            except:
-                pass
-            res.append(o)
-    return res
-
-def get_or_create_task(task_name, config, target, scanner):
-    res = get_tasks(task_name)
-    if len(res) == 0:
-        t = create_task(task_name, config, target, scanner)
-        return get_tasks(t['id'])[0]
-    elif len(res) == 1:
-        return res[0]
-    else:
-        print(f"Found {len(res)} results. Return None")
-        return res
-
-def get_all_tasks():
-    res = []
-    gmp = create_connection()
-    tasks = gmp.get_tasks(filter_string="rows=-1")
-    for task in tasks.xpath('task'):
-            o = dict()
-            o['name'] = task.xpath('name/text()')[0]
-            o['id'] = task.xpath('@id')[0]
-            o['progress'] = task.xpath('progress/text()')[0]
-            o['in_use'] = task.xpath('in_use/text()')[0]
-            o['status'] = task.xpath('status/text()')[0]
-            o['target_id'] = task.xpath('target/@id')[0]
-            try:
-                o['report_id'] = task.xpath('last_report/report/@id')[0]
-            except:
-                pass
-            res.append(o)
-    return res
-
-def search_and_delete_all_tasks(filter_str):
-    tasks = get_tasks(filter_str)
-    for task in tasks:
-        delete_task(task)
-
-def start_task(task):
-    gmp = create_connection()
-    res = gmp.start_task(task['id'])
-    task['report_id'] = res.xpath('report_id/text()')[0]
-    return task        
-
-def stop_task(task):
-    gmp = create_connection()
-    res = gmp.stop_task(task['id'])
-    pretty_print(res)
-
-def delete_task(task):
-    gmp = create_connection()
-    res = gmp.delete_task(task['id'])
-    status = res.xpath('@status')[0]
-    status_text = res.xpath('@status_text')[0]
-    if status == "200":
-        print(f"Target with id: {task['id']} and name: {task['name']} DELETED") 
-    else:
-        print(f"ERROR {status}: {status_text}")
-
-############## REPORTS #####################################3
-
-class report_formats:
-    anonymous_xml = "5057e5cc-b825-11e4-9d0e-28d24461215b"
-    csv_results   = "c1645568-627a-11e3-a660-406186ea4fc5"
-    itg           = "77bd6c4a-1f62-11e1-abf0-406186ea4fc5"
-    pdf           = "c402cc3e-b531-11e1-9163-406186ea4fc5"
-    txt           = "a3810a62-1f62-11e1-9219-406186ea4fc5"
-    xml           = "a994b278-1f62-11e1-96ac-406186ea4fc5"
-
-def get_report_formats():
-    gmp = create_connection()  
-    res =  gmp.get_report_formats()
-    for f in res.xpath('report_format'):
-        name = f.xpath('name/text()')[0]
-        id = f.xpath('@id')[0]
-        print(id,name)
-
-def get_report_format(id):
-    gmp = create_connection()
-    res =  gmp.get_report_formats()
-    pretty_print(res)  
-
-def get_progress(task):
-    task_info = get_tasks(task['id'])[0]
-    status = task_info['status']         #   New -> Requested -> Queued -> Running  -> Done
-    progress = int(task_info['progress'])#    0         0           0      0 -> 100     -1
-    return status, progress
-
-def wait_for_task_completition(task, timeout=3600):
-    start_time = time()
-    while True:
-        status, progress = get_progress(task)
-        if status not in ["New","Requested","Queued","Running","Done"]: # ["Interrupted", ...]
-            return False
-        if status == "Done" and progress == -1:
-            return True
-        if time() - start_time > timeout:
-                print("TIMEOUT during waiting for task completition")
-                return False
-        sleep(60)
-
-def save_report(task,report_format_id, report_filename ):
-    gmp = create_connection()
-    res = gmp.get_report(task['report_id'],
-                                report_format_id=report_format_id, 
-                                ignore_pagination=True,
-                                details="1")
-    code = str(res.xpath('report/text()')[0])
-    with open(report_filename, "wb") as fh:
-        fh.write(base64.b64decode(code))
-
-def save_severity_report(task, severity_filename):
-    dict_severity = {"Log": 0, "Low": 1, "Medium": 2, "High": 3}
-    gmp = create_connection()
-    res = gmp.get_report(task['report_id'],
-                        report_format_id=report_formats.anonymous_xml, 
-                        ignore_pagination=True,
-                        details="1")
-    severities = res.xpath('report/report/ports/port/threat/text()')
-    old_num_severity = 0
-    severity = "Log"
-    for sev in severities:
-        if dict_severity[sev] > old_num_severity:
-            old_num_severity = dict_severity[sev]
-            severity = sev
-    with open(severity_filename, "w") as f:
-        f.write(severity)
-
-def get_severity(task):
-    dict_severity = {"Log": 0, "Low": 1, "Medium": 2, "High": 3}
-    gmp = create_connection()
-    res = gmp.get_report(task['report_id'],
-                        report_format_id=report_formats.anonymous_xml, 
-                        ignore_pagination=True,
-                        details="1")
-    severities = res.xpath('report/report/ports/port/threat/text()')
-    old_num_severity = 0
-    severity = "Log"
-    for sev in severities:
-        if dict_severity[sev] > old_num_severity:
-            old_num_severity = dict_severity[sev]
-            severity = sev
-    return severity
-            
-def get_reports(filter_str="rows=-1"):
-    lo = []
-    gmp = create_connection()
-    reports = gmp.get_reports(filter_string = filter_str)
-    for report in reports.xpath('report'):
-        o = dict()
-        o['task_name'] = report.xpath('task/name/text()')[0]
-        o['id'] = report.xpath('@id')[0]
-        lo.append(o)
-    return lo
-
-def get_numeric_severity(severity):
-    if severity == "Log":
-        return 0
-    elif severity == "Low":
-        return 1
-    elif severity == "Medium":
-        return 2
-    elif severity == "High":
-        return 3
-    else:
-        return 4
-
-def get_severity_from_number(num):
-    if num == 0:
-        return "Low"
-    elif num == 1:
-        return "Low"
-    elif num == 2:
-        return "Medium"
-    elif num == 3:
-        return "High"
-    else:
-        return "Undefined"
-
-def process_global_severity(severities):
-    max_num_severity = 0
-    for _,sev in severities.items():
-        numeric_severity = get_numeric_severity(sev)
-        if numeric_severity > max_num_severity:
-            max_num_severity = numeric_severity
-    severities['global_severity'] = get_severity_from_number(max_num_severity)
-    if max_num_severity < 2:
-        severities['global'] = "OK"
-    else:
-        severities['global'] = "NOK"
-    return severities
-
-def print_pretty_json(j):
-    print(json.dumps(j,sort_keys=True,indent=4))
-        
-def import_dep_info(file_path, endpoints_to_scan):
-    with open(file_path) as f:
-        data = json.load(f)
-
-    endpoints = dict()
-    for key in data['outputs'].keys():
-        if key in endpoints_to_scan:
-            endpoint = str(data['outputs'][key])
-            prefix,url = endpoint.split("://")
-            if ":" in url:
-                host,port = url.split(":")
-            else:
-                host = url
-                if prefix == "https":
-                    port = '443'
-                elif prefix == 'http':
-                    port = '80'
-                else:
-                    raise Exception(f"Impossible to parse the endpoint port. Endpoint: {endpoint}")
-            print(f"Endpoint: {host}:{port}")
-            if host not in endpoints:
-                endpoints[host] = {"22"}
-            endpoints[host].add(port)
-    return endpoints
-                
-################ MAIN #######################################
-
-auth_name = os.getenv('GMP_USER')
-auth_passwd = os.getenv('GMP_PASSWORD')
-print(auth_name, auth_passwd)
-logging.basicConfig(filename='debug.log', level=logging.DEBUG)
-#local_ip = socket.gethostbyname(socket.gethostname())
-#local_ip = '127.0.0.1'
-local_ip = os.getenv('HOST_IP')
-connection = TLSConnection(hostname=local_ip)
-transform = EtreeTransform()
-config = {'id':"9866edc1-8869-4e80-acac-d15d5647b4d9"}
-scanner = {'id': "08b69003-5fc2-4037-a479-93b440211c73"}
-ovs_ssh_credential = {'id': "b9af5845-8b87-4378-bca4-cee39a894c17"}
-wait_timeout = 3600 #1h
-
-if len(argv) != 4:
-    print("Please pass three parameters:")
-    print("- endpoints to scans [endpoints1,endpoint2,endpoint3,...]")
-    print("- dep.json path [/home/gmp/workspace/dep.json]")
-    print("- output directory [/home/gmp/workspace]")
-    exit(1)
-
-endpoints_to_scan = argv[1].split(',')
-dep_json = argv[2]
-output_dir = argv[3]
-print("endpoints_to_scan", endpoints_to_scan)
-print("dep_json", dep_json)
-print("output_dir", output_dir)
-
-endpoints = import_dep_info(dep_json, endpoints_to_scan)
-#print_pretty_json(endpoints)      
-
-# test gmp connection
-get_version()
-
-severities = dict()
-for host,ports in endpoints.items():
-    print(host,ports)
-  
-    target_name = f"{auth_name}_target_{host}"
-    task_name = f"{auth_name}_task_{host}"
-    port_list_name = f"{auth_name}_pl_{host}"
-    report_filename = f"{output_dir}/{host}-report.txt"
-    severity_filename = f"{output_dir}/severity.json"
-
-    port_list = get_or_create_port_list(port_list_name,ports)
-    print_pretty_json(port_list)
-    target = get_or_create_target(target_name,host,port_list,ovs_ssh_credential)
-    print_pretty_json(target)
-    task = get_or_create_task(task_name, config, target,scanner)
-    print_pretty_json(task)
-    if task['status'] == 'New':
-        task = start_task(task)
-    if wait_for_task_completition(task,wait_timeout):
-        save_report(task,report_formats.txt, report_filename)
-        severities[host] = get_severity(task)
-    else:
-        severities[host] = f"ERROR Task: {task['id']}"
-    delete_task(task)
-    delete_target(target)
-    delete_port_list(port_list)
-
-severities = process_global_severity(severities)
-with open(severity_filename, "w") as f:
-    f.write(json.dumps(severities))
diff --git a/jenkinsfile/Jenkinsfile b/jenkinsfile/Jenkinsfile
index b0cfd57..64bb44e 100644
--- a/jenkinsfile/Jenkinsfile
+++ b/jenkinsfile/Jenkinsfile
@@ -13,6 +13,8 @@ pipeline {
                     eval `oidc-agent-service use`
                     oidc-add infn-cloud-ops
                     
+                    env
+                    
                     # Orchent connection test
                     orchent depls > depls.output
                     if cat depls.output | grep -q ERROR
@@ -25,8 +27,7 @@ pipeline {
                     fi
 
                     # Greenbone connection test
-                    export HOST_IP=`/sbin/ip route list scope link | grep -v " 172." | awk '{print $7}' | tr -d '\n'`
-                    gvm-cli --gmp-username $GMP_USERNAME --gmp-password $GMP_PASSWD tls --hostname $HOST_IP --xml "<get_version/>"
+                    /usr/local/bin/gvm-cli --gmp-username $GMP_USERNAME --gmp-password $GMP_PASSWD tls --hostname $HOST_IP --xml "<get_version/>"
 
                 '''
             }
-- 
GitLab