def create_scan_config(self, config_id: str, name: str, *, comment: Optional[str] = None) -> Any: """Create a new scan config Arguments: config_id: UUID of the existing scan config name: Name of the new scan config comment: A comment on the config Returns: The response. See :py:meth:`send_command` for details. """ if not name: raise RequiredArgument(function=self.create_scan_config.__name__, argument="name") if not config_id: raise RequiredArgument(function=self.create_scan_config.__name__, argument="config_id") cmd = XmlCommand("create_config") if comment is not None: cmd.add_element("comment", comment) cmd.add_element("copy", config_id) cmd.add_element("name", name) cmd.add_element("usage_type", "scan") return self._send_xml_command(cmd)
def modify_scan_config_set_name(self, config_id: str, name: str) -> Any: """Modifies the name of an existing scan config Arguments: config_id: UUID of scan config to modify. name: New name for the config. """ if not config_id: raise RequiredArgument( function=self.modify_scan_config_set_name.__name__, argument="config_id", ) if not name: raise RequiredArgument( function=self.modify_scan_config_set_name.__name__, argument="name", ) cmd = XmlCommand("modify_config") cmd.set_attribute("config_id", str(config_id)) cmd.add_element("name", name) return self._send_xml_command(cmd)
def modify_auth(self, group_name: str, auth_conf_settings: dict) -> Any: """Modifies an existing auth. Arguments: group_name: Name of the group to be modified. auth_conf_settings: The new auth config. Returns: The response. See :py:meth:`send_command` for details. """ if not group_name: raise RequiredArgument(function=self.modify_auth.__name__, argument="group_name") if not auth_conf_settings: raise RequiredArgument( function=self.modify_auth.__name__, argument="auth_conf_settings", ) cmd = XmlCommand("modify_auth") _xmlgroup = cmd.add_element("group", attrs={"name": str(group_name)}) for key, value in auth_conf_settings.items(): _xmlauthconf = _xmlgroup.add_element("auth_conf_setting") _xmlauthconf.add_element("key", key) _xmlauthconf.add_element("value", value) return self._send_xml_command(cmd)
def create_port_list(self, name: str, port_range: str, *, comment: Optional[str] = None) -> Any: """Create a new port list Arguments: name: Name of the new port list port_range: Port list ranges e.g. `"T: 1-1234"` for tcp port 1 - 1234 comment: Comment for the port list Returns: The response. See :py:meth:`send_command` for details. """ if not name: raise RequiredArgument(function=self.create_port_list.__name__, argument="name") if not port_range: raise RequiredArgument(function=self.create_port_list.__name__, argument="port_range") cmd = XmlCommand("create_port_list") cmd.add_element("name", name) cmd.add_element("port_range", port_range) if comment: cmd.add_element("comment", comment) return self._send_xml_command(cmd)
def get_info(self, info_id: str, info_type: InfoType) -> Any: """Request a single secinfo Arguments: info_id: UUID of an existing secinfo info_type: Type must be either CERT_BUND_ADV, CPE, CVE, DFN_CERT_ADV, OVALDEF, NVT Returns: The response. See :py:meth:`send_command` for details. """ if not info_type: raise RequiredArgument(function=self.get_info.__name__, argument='info_type') if not isinstance(info_type, InfoType): raise InvalidArgumentType( function=self.get_info.__name__, argument='info_type', arg_type=InfoType.__name__, ) if not info_id: raise RequiredArgument(function=self.get_info.__name__, argument='info_id') cmd = XmlCommand("get_info") cmd.set_attribute("info_id", info_id) cmd.set_attribute("type", info_type.value) # for single entity always request all details cmd.set_attribute("details", "1") return self._send_xml_command(cmd)
def modify_ticket( self, ticket_id: str, *, status: Optional[TicketStatus] = None, note: Optional[str] = None, assigned_to_user_id: Optional[str] = None, comment: Optional[str] = None ) -> Any: """Modify a single ticket Arguments: ticket_id: UUID of an existing ticket status: New status for the ticket note: Note for the status change. Required if status is set. assigned_to_user_id: UUID of the user the ticket should be assigned to comment: Comment for the ticket Returns: The response. See :py:meth:`send_command` for details. """ if not ticket_id: raise RequiredArgument( function=self.modify_ticket.__name__, argument='ticket_id' ) if status and not note: raise RequiredArgument( function=self.modify_ticket.__name__, argument='note', ) if note and not status: raise RequiredArgument( function=self.modify_ticket.__name__, argument='status', ) cmd = XmlCommand("modify_ticket") cmd.set_attribute("ticket_id", ticket_id) if assigned_to_user_id: _assigned = cmd.add_element("assigned_to") _user = _assigned.add_element("user") _user.set_attribute("id", assigned_to_user_id) if status: if not isinstance(status, TicketStatus): raise InvalidArgumentType( function=self.modify_ticket.__name__, argument='status', arg_type=TicketStatus.__name__, ) cmd.add_element('status', status.value) cmd.add_element('{}_note'.format(status.name.lower()), note) if comment: cmd.add_element("comment", comment) return self._send_xml_command(cmd)
def authenticate(self, username: str, password: str) -> Any: """Authenticate to gvmd. The generated authenticate command will be send to server. Afterwards the response is read, transformed and returned. Arguments: username: Username password: Password Returns: Transformed response from server. """ cmd = XmlCommand("authenticate") if not username: raise RequiredArgument(function=self.authenticate.__name__, argument="username") if not password: raise RequiredArgument(function=self.authenticate.__name__, argument="password") credentials = cmd.add_element("credentials") credentials.add_element("username", username) credentials.add_element("password", password) self._send(cmd.to_string()) response = self._read() if check_command_status(response): self._authenticated = True return self._transform(response)
def create_port_range( self, port_list_id: str, start: int, end: int, port_range_type: PortRangeType, *, comment: Optional[str] = None, ) -> Any: """Create new port range Arguments: port_list_id: UUID of the port list to which to add the range start: The first port in the range end: The last port in the range port_range_type: The type of the ports: TCP, UDP, ... comment: Comment for the port range Returns: The response. See :py:meth:`send_command` for details. """ if not port_list_id: raise RequiredArgument( function=self.create_port_range.__name__, argument="port_list_id", ) if not port_range_type: raise RequiredArgument( function=self.create_port_range.__name__, argument="port_range_type", ) if not start: raise RequiredArgument(function=self.create_port_range.__name__, argument="start") if not end: raise RequiredArgument(function=self.create_port_range.__name__, argument="end") if not isinstance(port_range_type, PortRangeType): raise InvalidArgumentType( function=self.create_port_range.__name__, argument="port_range_type", arg_type=PortRangeType.__name__, ) cmd = XmlCommand("create_port_range") cmd.add_element("port_list", attrs={"id": port_list_id}) cmd.add_element("start", str(start)) cmd.add_element("end", str(end)) cmd.add_element("type", port_range_type.value) if comment: cmd.add_element("comment", comment) return self._send_xml_command(cmd)
def trigger_alert( self, alert_id: str, report_id: str, *, filter_string: Optional[str] = None, filter_id: Optional[str] = None, report_format_id: Optional[Union[str, ReportFormatType]] = None, delta_report_id: Optional[str] = None, ) -> Any: """Run an alert by ignoring its event and conditions The alert is triggered to run immediately with the provided filtered report by ignoring the even and condition settings. Arguments: alert_id: UUID of the alert to be run report_id: UUID of the report to be provided to the alert filter: Filter term to use to filter results in the report filter_id: UUID of filter to use to filter results in the report report_format_id: UUID of report format to use or ReportFormatType (enum) delta_report_id: UUID of an existing report to compare report to. Returns: The response. See :py:meth:`send_command` for details. """ if not alert_id: raise RequiredArgument( function=self.trigger_alert.__name__, argument="alert_id argument", ) if not report_id: raise RequiredArgument( function=self.trigger_alert.__name__, argument="report_id argument", ) cmd = XmlCommand("get_reports") cmd.set_attribute("report_id", report_id) cmd.set_attribute("alert_id", alert_id) add_filter(cmd, filter_string, filter_id) if report_format_id: if isinstance(report_format_id, ReportFormatType): report_format_id = report_format_id.value cmd.set_attribute("format_id", report_format_id) if delta_report_id: cmd.set_attribute("delta_report_id", delta_report_id) return self._send_xml_command(cmd)
def __create_config(self, config_id: str, name: str, usage_type: UsageType, function: str) -> Any: if not name: raise RequiredArgument(function=function, argument='name') if not config_id: raise RequiredArgument(function=function, argument='config_id') cmd = XmlCommand("create_config") cmd.add_element("copy", config_id) cmd.add_element("name", name) cmd.add_element("usage_type", usage_type.value) return self._send_xml_command(cmd)
def create_ticket( self, *, result_id: str, assigned_to_user_id: str, note: str, comment: Optional[str] = None ) -> Any: """Create a new ticket Arguments: result_id: UUID of the result the ticket applies to assigned_to_user_id: UUID of a user the ticket should be assigned to note: A note about opening the ticket comment: Comment for the ticket Returns: The response. See :py:meth:`send_command` for details. """ if not result_id: raise RequiredArgument( function=self.create_ticket.__name__, argument='result_id' ) if not assigned_to_user_id: raise RequiredArgument( function=self.create_ticket.__name__, argument='assigned_to_user_id', ) if not note: raise RequiredArgument( function=self.create_ticket.__name__, argument='note' ) cmd = XmlCommand("create_ticket") _result = cmd.add_element("result") _result.set_attribute("id", result_id) _assigned = cmd.add_element("assigned_to") _user = _assigned.add_element("user") _user.set_attribute("id", assigned_to_user_id) _note = cmd.add_element("open_note", note) if comment: cmd.add_element("comment", comment) return self._send_xml_command(cmd)
def test_raise_with_function(self): with self.assertRaises(RequiredArgument) as cm: raise RequiredArgument(function="foo") ex = cm.exception self.assertEqual(ex.function, "foo") self.assertIsNone(ex.argument)
def get_scan_config_preference( self, name: str, *, nvt_oid: Optional[str] = None, config_id: Optional[str] = None, ) -> Any: """Request a nvt preference Arguments: name: name of a particular preference nvt_oid: OID of nvt config_id: UUID of scan config of which to show preference values Returns: The response. See :py:meth:`send_command` for details. """ cmd = XmlCommand("get_preferences") if not name: raise RequiredArgument( function=self.get_scan_config_preference.__name__, argument="name", ) cmd.set_attribute("preference", name) if nvt_oid: cmd.set_attribute("nvt_oid", nvt_oid) if config_id: cmd.set_attribute("config_id", config_id) return self._send_xml_command(cmd)
def get_scan_config(self, config_id: str, *, tasks: Optional[bool] = None) -> Any: """Request a single scan config Arguments: config_id: UUID of an existing scan config tasks: Whether to get tasks using this config Returns: The response. See :py:meth:`send_command` for details. """ if not config_id: raise RequiredArgument(function=self.get_scan_config.__name__, argument="config_id") cmd = XmlCommand("get_configs") cmd.set_attribute("config_id", config_id) cmd.set_attribute("usage_type", "scan") if tasks is not None: cmd.set_attribute("tasks", to_bool(tasks)) # for single entity always request all details cmd.set_attribute("details", "1") return self._send_xml_command(cmd)
def get_schedule(self, schedule_id: str, *, tasks: Optional[bool] = None) -> Any: """Request a single schedule Arguments: schedule_id: UUID of an existing schedule tasks: Whether to include tasks using the schedules Returns: The response. See :py:meth:`send_command` for details. """ cmd = XmlCommand("get_schedules") if not schedule_id: raise RequiredArgument(function=self.get_schedule.__name__, argument="schedule_id") cmd.set_attribute("schedule_id", schedule_id) if tasks is not None: cmd.set_attribute("tasks", to_bool(tasks)) return self._send_xml_command(cmd)
def create_container_task(self, name: str, *, comment: Optional[str] = None) -> Any: """Create a new container task A container task is a "meta" task to import and view reports from other systems. Arguments: name: Name of the task comment: Comment for the task Returns: The response. See :py:meth:`send_command` for details. """ if not name: raise RequiredArgument( function=self.create_container_task.__name__, argument="name") cmd = XmlCommand("create_task") cmd.add_element("name", name) cmd.add_element("target", attrs={"id": "0"}) if comment: cmd.add_element("comment", comment) return self._send_xml_command(cmd)
def get_filter( self, filter_id: str, *, alerts: Optional[bool] = None ) -> Any: """Request a single filter Arguments: filter_id: UUID of an existing filter alerts: Whether to include list of alerts that use the filter. Returns: The response. See :py:meth:`send_command` for details. """ cmd = XmlCommand("get_filters") if not filter_id: raise RequiredArgument( function=self.get_filter.__name__, argument="filter_id" ) cmd.set_attribute("filter_id", filter_id) if alerts is not None: cmd.set_attribute("alerts", to_bool(alerts)) return self._send_xml_command(cmd)
def create_policy(self, name: str, *, policy_id: str = None, comment: Optional[str] = None) -> Any: """Create a new policy Arguments: name: Name of the new policy policy_id: UUID of an existing policy as base. By default the empty policy is used. comment: A comment on the policy Returns: The response. See :py:meth:`send_command` for details. """ cmd = XmlCommand("create_config") if policy_id is None: policy_id = _EMPTY_POLICY_ID if not name: raise RequiredArgument(function=self.create_policy.__name__, argument="name") if comment is not None: cmd.add_element("comment", comment) cmd.add_element("copy", policy_id) cmd.add_element("name", name) cmd.add_element("usage_type", "policy") return self._send_xml_command(cmd)
def modify_policy_set_family_selection( self, policy_id: str, families: List[Tuple[str, bool, bool]], *, auto_add_new_families: Optional[bool] = True, ) -> Any: """ Selected the NVTs of a policy at a family level. Arguments: policy_id: UUID of policy to modify. families: A list of tuples with the first entry being the name of the NVT family selected, second entry a boolean indicating whether new NVTs should be added to the family automatically, and third entry a boolean indicating whether all nvts from the family should be included. auto_add_new_families: Whether new families should be added to the policy automatically. Default: True. """ if not policy_id: raise RequiredArgument( function=self.modify_policy_set_family_selection.__name__, argument="policy_id", ) if not is_list_like(families): raise InvalidArgumentType( function=self.modify_policy_set_family_selection.__name__, argument="families", arg_type="list", ) cmd = XmlCommand("modify_config") cmd.set_attribute("config_id", str(policy_id)) _xmlfamsel = cmd.add_element("family_selection") _xmlfamsel.add_element("growing", to_bool(auto_add_new_families)) for family in families: _xmlfamily = _xmlfamsel.add_element("family") _xmlfamily.add_element("name", family[0]) if len(family) != 3: raise InvalidArgument( "Family must be a tuple of 3. (str, bool, bool)") if not isinstance(family[1], bool) or not isinstance( family[2], bool): raise InvalidArgumentType( function=( self.modify_policy_set_family_selection.__name__), argument="families", arg_type="[tuple(str, bool, bool)]", ) _xmlfamily.add_element("all", to_bool(family[2])) _xmlfamily.add_element("growing", to_bool(family[1])) return self._send_xml_command(cmd)
def modify_port_list( self, port_list_id: str, *, comment: Optional[str] = None, name: Optional[str] = None, ) -> Any: """Modifies an existing port list. Arguments: port_list_id: UUID of port list to modify. name: Name of port list. comment: Comment on port list. Returns: The response. See :py:meth:`send_command` for details. """ if not port_list_id: raise RequiredArgument(function=self.modify_port_list.__name__, argument="port_list_id") cmd = XmlCommand("modify_port_list") cmd.set_attribute("port_list_id", port_list_id) if comment: cmd.add_element("comment", comment) if name: cmd.add_element("name", name) return self._send_xml_command(cmd)
def get_tls_certificate(self, tls_certificate_id: str) -> Any: """Request a single TLS certificate Arguments: tls_certificate_id: UUID of an existing TLS certificate Returns: The response. See :py:meth:`send_command` for details. """ cmd = XmlCommand("get_tls_certificates") if not tls_certificate_id: raise RequiredArgument( function=self.get_tls_certificate.__name__, argument='tls_certificate_id', ) cmd.set_attribute("tls_certificate_id", tls_certificate_id) # for single tls certificate always request cert data cmd.set_attribute("include_certificate_data", "1") # for single entity always request all details cmd.set_attribute("details", "1") return self._send_xml_command(cmd)
def test_raise_with_argument(self): with self.assertRaises(RequiredArgument) as cm: raise RequiredArgument(argument='foo') ex = cm.exception self.assertEqual(ex.argument, 'foo') self.assertIsNone(ex.function)
def test_raise_with_argument_and_function(self): with self.assertRaises(RequiredArgument) as cm: raise RequiredArgument(argument='foo', function='bar') ex = cm.exception self.assertEqual(ex.argument, 'foo') self.assertEqual(ex.function, 'bar')
def get_target(self, target_id: str, *, tasks: Optional[bool] = None) -> Any: """Request a single target Arguments: target_id: UUID of an existing target tasks: Whether to include list of tasks that use the target Returns: The response. See :py:meth:`send_command` for details. """ cmd = XmlCommand("get_targets") if not target_id: raise RequiredArgument(function=self.get_target.__name__, argument="target_id") cmd.set_attribute("target_id", target_id) if tasks is not None: cmd.set_attribute("tasks", to_bool(tasks)) return self._send_xml_command(cmd)
def modify_scan_config_set_comment(self, config_id: str, *, comment: Optional[str] = None) -> Any: """Modifies the comment of an existing scan config Arguments: config_id: UUID of scan config to modify. comment: Comment to set on a config. Default is an empty comment and the previous comment will be removed. """ if not config_id: raise RequiredArgument( function=self.modify_scan_config_set_comment.__name__, argument="config_id argument", ) cmd = XmlCommand("modify_config") cmd.set_attribute("config_id", str(config_id)) if not comment: comment = "" cmd.add_element("comment", comment) return self._send_xml_command(cmd)
def test_raise_with_argument_and_function(self): with self.assertRaises(RequiredArgument) as cm: raise RequiredArgument(argument="foo", function="bar") ex = cm.exception self.assertEqual(ex.argument, "foo") self.assertEqual(ex.function, "bar")
def modify_operating_system(self, operating_system_id: str, *, comment: Optional[str] = None) -> Any: """Modifies an existing operating system. Arguments: operating_system_id: UUID of the operating_system to be modified. comment: Comment for the operating_system. Not passing a comment arguments clears the comment for this operating system. Returns: The response. See :py:meth:`send_command` for details. """ if not operating_system_id: raise RequiredArgument( function=self.modify_operating_system.__name__, argument="operating_system_id", ) cmd = XmlCommand("modify_asset") cmd.set_attribute("asset_id", operating_system_id) if not comment: comment = "" cmd.add_element("comment", comment) return self._send_xml_command(cmd)
def create_role( self, name: str, *, comment: Optional[str] = None, users: Optional[List[str]] = None, ) -> Any: """Create a new role Arguments: name: Name of the role comment: Comment for the role users: List of user names to add to the role Returns: The response. See :py:meth:`send_command` for details. """ if not name: raise RequiredArgument(function=self.create_role.__name__, argument="name") cmd = XmlCommand("create_role") cmd.add_element("name", name) if comment: cmd.add_element("comment", comment) if users: cmd.add_element("users", to_comma_list(users)) return self._send_xml_command(cmd)
def get_policy(self, policy_id: str, *, audits: Optional[bool] = None) -> Any: """Request a single policy Arguments: policy_id: UUID of an existing policy audits: Whether to get audits using this policy Returns: The response. See :py:meth:`send_command` for details. """ if not policy_id: raise RequiredArgument(function=self.get_policy.__name__, argument="policy_id") cmd = XmlCommand("get_configs") cmd.set_attribute("config_id", policy_id) cmd.set_attribute("usage_type", "policy") if audits is not None: cmd.set_attribute("tasks", to_bool(audits)) # for single entity always request all details cmd.set_attribute("details", "1") return self._send_xml_command(cmd)
def modify_scan_config_set_nvt_preference( self, config_id: str, name: str, nvt_oid: str, *, value: Optional[str] = None, ) -> Any: """Modifies the nvt preferences of an existing scan config. Arguments: config_id: UUID of scan config to modify. name: Name for nvt preference to change. nvt_oid: OID of the NVT associated with preference to modify value: New value for the preference. None to delete the preference and to use the default instead. """ if not config_id: raise RequiredArgument( function=self.modify_scan_config_set_nvt_preference.__name__, argument="config_id", ) if not nvt_oid: raise RequiredArgument( function=self.modify_scan_config_set_nvt_preference.__name__, argument="nvt_oid", ) if not name: raise RequiredArgument( function=self.modify_scan_config_set_nvt_preference.__name__, argument="name", ) cmd = XmlCommand("modify_config") cmd.set_attribute("config_id", str(config_id)) _xmlpref = cmd.add_element("preference") _xmlpref.add_element("nvt", attrs={"oid": nvt_oid}) _xmlpref.add_element("name", name) if value: _xmlpref.add_element("value", to_base64(value)) return self._send_xml_command(cmd)