1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
|
# SPDX-FileCopyrightText: 2018-2021 Greenbone AG
#
# SPDX-License-Identifier: GPL-3.0-or-later
import sys
from argparse import ArgumentParser, Namespace, RawTextHelpFormatter
from gvm.protocols.gmp import Gmp
from gvmtools.helper import create_xml_tree, error_and_exit, yes_or_no
HELP_TEXT = """
This script pulls tasks data from an xml document and feeds it to \
a desired GSM
Usage examples:
$ gvm-script --gmp-username name --gmp-password pass ssh --hostname
... send-task.gmp.py +h
... send-task.gmp.py ++x xml_file
"""
def numerical_option(statement, list_range):
choice = int(input(statement))
if choice in range(1, list_range + 1):
return choice
else:
return numerical_option(
f"Please enter valid number from 1 to {list_range}...",
list_range,
)
def interactive_options(gmp, task, keywords):
options_dict = {}
options_dict["config"] = gmp.get_scan_configs()
options_dict["scanner"] = gmp.get_scanners()
options_dict["target"] = gmp.get_targets()
for option_key, option_value in options_dict.items():
object_dict, object_list = {}, []
object_id = task.find(option_key).get("id")
object_xml = option_value
for i in object_xml.findall(option_key):
object_dict[i.find("name").text] = i.xpath("@id")[0]
object_list.append(i.find("name").text)
if object_id in object_dict.values():
keywords[f"{option_key}_id"] = object_id
elif object_id not in object_dict.values() and len(object_dict) != 0:
response = yes_or_no(
f"\nRequired Field: failed to detect {option_key}_id: "
f"{task.xpath(f'{option_key}/@id')[0]}... "
"\nWould you like to select from available options, or exit "
"the script?"
)
if response is True:
counter = 1
print(f"{option_key.capitalize()} options:")
for j in object_list:
print(f" {counter} - {j}")
counter += 1
answer = numerical_option(
"\nPlease enter the number of your choice.",
len(object_list),
)
keywords[f"{option_key}_id"] = object_dict[
object_list[answer - 1]
]
else:
print("\nTerminating...")
sys.exit()
else:
error_and_exit(
f"Failed to detect {option_key}_id\nThis field is required "
"therefore the script is unable to continue.\n"
)
def parse_send_xml_tree(gmp, xml_tree):
task_xml_elements = xml_tree.xpath("task")
print(task_xml_elements)
if not task_xml_elements:
error_and_exit("No tasks found.")
tasks = []
for task in task_xml_elements:
keywords = {"name": task.find("name").text}
if task.find("comment").text is not None:
keywords["comment"] = task.find("comment").text
interactive_options(gmp, task, keywords)
if task.find("schedule_periods") is not None:
keywords["schedule_periods"] = int(
task.find("schedule_periods").text
)
if task.find("observers").text:
keywords["observers"] = task.find("observers").text
if task.xpath("schedule/@id")[0]:
keywords["schedule_id"] = task.xpath("schedule/@id")[0]
if task.xpath("preferences/preference"):
preferences, scanner_name_list, value_list = {}, [], []
for preference in task.xpath("preferences/preference"):
scanner_name_list.append(preference.find("scanner_name").text)
if preference.find("value").text is not None:
value_list.append(preference.find("value").text)
else:
value_list.append("")
preferences["scanner_name"] = scanner_name_list
preferences["value"] = value_list
keywords["preferences"] = preferences
new_task = gmp.create_task(**keywords)
tasks.append(new_task.xpath("//@id")[0])
return tasks
def main(gmp: Gmp, args: Namespace) -> None:
# pylint: disable=undefined-variable, unused-argument
parser = ArgumentParser(
prefix_chars="+",
add_help=False,
formatter_class=RawTextHelpFormatter,
description=HELP_TEXT,
)
parser.add_argument(
"+h",
"++help",
action="help",
help="Show this help message and exit.",
)
parser.add_argument(
"+x",
"++xml-file",
dest="xml",
type=str,
required=True,
help="xml file containing tasks",
)
script_args, _ = parser.parse_known_args()
# check_args(args)
print("\nSending task(s)...")
xml_tree = create_xml_tree(script_args.xml)
tasks = parse_send_xml_tree(gmp, xml_tree)
for task in tasks:
print(task)
print("\nTask(s) sent!\n")
if __name__ == "__gmp__":
main(gmp, args) # pylint: disable=undefined-variable
|