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_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 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 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 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 create_user( self, name: str, *, password: Optional[str] = None, hosts: Optional[List[str]] = None, hosts_allow: Optional[bool] = False, ifaces: Optional[List[str]] = None, ifaces_allow: Optional[bool] = False, role_ids: Optional[List[str]] = None, ) -> Any: """Create a new user Arguments: name: Name of the user password: Password of the user hosts: A list of host addresses (IPs, DNS names) hosts_allow: If True allow only access to passed hosts otherwise deny access. Default is False for deny hosts. ifaces: A list of interface names ifaces_allow: If True allow only access to passed interfaces otherwise deny access. Default is False for deny interfaces. role_ids: A list of role UUIDs for the user Returns: The response. See :py:meth:`send_command` for details. """ if not name: raise RequiredArgument(function=self.create_user.__name__, argument="name") cmd = XmlCommand("create_user") cmd.add_element("name", name) if password: cmd.add_element("password", password) if hosts: cmd.add_element( "hosts", to_comma_list(hosts), attrs={"allow": to_bool(hosts_allow)}, ) if ifaces: cmd.add_element( "ifaces", to_comma_list(ifaces), attrs={"allow": to_bool(ifaces_allow)}, ) if role_ids: for role in role_ids: cmd.add_element("role", attrs={"id": role}) 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 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 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_xml_escaping(self): cmd = XmlCommand('foo') cmd.add_element('bar', 'Foo & Bar') self.assertEqual(cmd.to_string(), '<foo><bar>Foo & Bar</bar></foo>') cmd = XmlCommand('foo') cmd.set_attribute('bar', 'Foo & Bar') self.assertEqual(cmd.to_string(), '<foo bar="Foo & Bar"/>') cmd = XmlCommand('foo') cmd.set_attribute('bar', 'Foo "Bar"') self.assertEqual(cmd.to_string(), '<foo bar="Foo "Bar""/>')
def create_user( self, name: str, *, password: Optional[str] = None, hosts: Optional[List[str]] = None, hosts_allow: Optional[bool] = False, ifaces: Any = None, ifaces_allow: Any = None, role_ids: Optional[List[str]] = None, ) -> Any: """Create a new user Arguments: name: Name of the user password: Password of the user hosts: A list of host addresses (IPs, DNS names) hosts_allow: If True allow only access to passed hosts otherwise deny access. Default is False for deny hosts. ifaces: deprecated ifaces_allow: deprecated role_ids: A list of role UUIDs for the user Returns: The response. See :py:meth:`send_command` for details. """ if not name: raise RequiredArgument(function=self.create_user.__name__, argument="name") cmd = XmlCommand("create_user") cmd.add_element("name", name) if password: cmd.add_element("password", password) if hosts: cmd.add_element( "hosts", to_comma_list(hosts), attrs={"allow": to_bool(hosts_allow)}, ) if ifaces is not None: major, minor = self.get_protocol_version() deprecation("The ifaces parameter has been removed in GMP" f" version {major}{minor}") if ifaces_allow is not None: major, minor = self.get_protocol_version() deprecation("The ifaces_allow parameter has been removed in GMP" f" version {major}{minor}") if role_ids: for role in role_ids: cmd.add_element("role", attrs={"id": role}) 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 clone_scan_config(self, config_id: str) -> Any: """Clone a scan config from an existing one Arguments: config_id: UUID of the existing scan config Returns: The response. See :py:meth:`send_command` for details. """ if not config_id: raise RequiredArgument(function=self.clone_scan_config.__name__, argument="config_id") cmd = XmlCommand("create_config") cmd.add_element("copy", config_id) return self._send_xml_command(cmd)
def clone_audit(self, audit_id: str) -> Any: """Clone an existing audit Arguments: audit_id: UUID of existing audit to clone from Returns: The response. See :py:meth:`send_command` for details. """ if not audit_id: raise RequiredArgument(function=self.clone_audit.__name__, argument='audit_id') cmd = XmlCommand("create_task") cmd.add_element("copy", audit_id) return self._send_xml_command(cmd)
def clone_role(self, role_id: str) -> Any: """Clone an existing role Arguments: role_id: UUID of an existing role to clone from Returns: The response. See :py:meth:`send_command` for details. """ if not role_id: raise RequiredArgument(function=self.clone_role.__name__, argument="role_id") cmd = XmlCommand("create_role") cmd.add_element("copy", role_id) return self._send_xml_command(cmd)
def clone_policy(self, policy_id: str) -> Any: """Clone a policy from an existing one Arguments: policy_id: UUID of the existing policy Returns: The response. See :py:meth:`send_command` for details. """ if not policy_id: raise RequiredArgument(function=self.clone_policy.__name__, argument='policy_id') cmd = XmlCommand("create_config") cmd.add_element("copy", policy_id) 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 clone_user(self, user_id: str) -> Any: """Clone an existing user Arguments: user_id: UUID of existing user to clone from Returns: The response. See :py:meth:`send_command` for details. """ if not user_id: raise RequiredArgument(function=self.clone_user.__name__, argument="user_id") cmd = XmlCommand("create_user") cmd.add_element("copy", user_id) return self._send_xml_command(cmd)
def clone_port_list(self, port_list_id: str) -> Any: """Clone an existing port list Arguments: port_list_id: UUID of an existing port list to clone from Returns: The response. See :py:meth:`send_command` for details. """ if not port_list_id: raise RequiredArgument(function=self.clone_port_list.__name__, argument="port_list_id") cmd = XmlCommand("create_port_list") cmd.add_element("copy", port_list_id) 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 modify_scan_config_set_family_selection( self, config_id: str, families: List[Tuple[str, bool, bool]], *, auto_add_new_families: Optional[bool] = True, ) -> Any: """ Selected the NVTs of a scan config at a family level. Arguments: config_id: UUID of scan config to modify. families: A list of tuples (str, bool, bool): str: the name of the NVT family selected, bool: add new NVTs to the family automatically, bool: include all NVTs from the family auto_add_new_families: Whether new families should be added to the scan config automatically. Default: True. """ if not config_id: raise RequiredArgument( function=self.modify_scan_config_set_family_selection.__name__, argument="config_id", ) if not is_list_like(families): raise InvalidArgumentType( function=self.modify_scan_config_set_family_selection.__name__, argument="families", arg_type="list", ) cmd = XmlCommand("modify_config") cmd.set_attribute("config_id", str(config_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_scan_config_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_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 clone_credential(self, credential_id: str) -> Any: """Clone an existing credential Arguments: credential_id: UUID of an existing credential to clone from Returns: The response. See :py:meth:`send_command` for details. """ if not credential_id: raise RequiredArgument( function=self.clone_credential.__name__, argument="credential_id", ) cmd = XmlCommand("create_credential") cmd.add_element("copy", credential_id) return self._send_xml_command(cmd)
def clone_tls_certificate(self, tls_certificate_id: str) -> Any: """Modifies an existing TLS certificate. Arguments: tls_certificate_id: The UUID of an existing TLS certificate Returns: The response. See :py:meth:`send_command` for details. """ if not tls_certificate_id: raise RequiredArgument( function=self.modify_tls_certificate.__name__, argument='tls_certificate_id', ) cmd = XmlCommand("create_tls_certificate") cmd.add_element("copy", tls_certificate_id) return self._send_xml_command(cmd)
def import_report( self, report: str, *, task_id: Optional[str] = None, in_assets: Optional[bool] = None, ) -> Any: """Import a Report from XML Arguments: report: Report XML as string to import. This XML must contain a :code:`<report>` root element. task_id: UUID of task to import report to in_asset: Whether to create or update assets using the report Returns: The response. See :py:meth:`send_command` for details. """ if not report: raise RequiredArgument(function=self.import_report.__name__, argument="report") cmd = XmlCommand("create_report") if task_id: cmd.add_element("task", attrs={"id": task_id}) else: raise RequiredArgument(function=self.import_report.__name__, argument="task_id") if in_assets is not None: cmd.add_element("in_assets", to_bool(in_assets)) try: cmd.append_xml_str(report) except XMLSyntaxError as e: raise InvalidArgument( f"Invalid xml passed as report to import_report {e}") from None 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 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 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 modify_schedule( self, schedule_id: str, *, name: Optional[str] = None, icalendar: Optional[str] = None, timezone: Optional[str] = None, comment: Optional[str] = None ) -> Any: """Modifies an existing schedule Arguments: schedule_id: UUID of the schedule to be modified name: Name of the schedule icalendar: `iCalendar`_ (RFC 5545) based data. timezone: Timezone to use for the icalender events e.g Europe/Berlin. If the datetime values in the icalendar data are missing timezone information this timezone gets applied. Otherwise the datetime values from the icalendar data are displayed in this timezone commenhedule. Returns: The response. See :py:meth:`send_command` for details. .. _iCalendar: https://tools.ietf.org/html/rfc5545 """ if not schedule_id: raise RequiredArgument( function=self.modify_schedule.__name__, argument='schedule_id' ) cmd = XmlCommand("modify_schedule") cmd.set_attribute("schedule_id", schedule_id) if name: cmd.add_element("name", name) if icalendar: cmd.add_element("icalendar", icalendar) if timezone: cmd.add_element("timezone", timezone) if comment: cmd.add_element("comment", comment) return self._send_xml_command(cmd)
def modify_user_setting( self, setting_id: Optional[str] = None, name: Optional[str] = None, value: Optional[str] = None, ) -> Any: """Modifies an existing user setting. Arguments: setting_id: UUID of the setting to be changed. name: The name of the setting. Either setting_id or name must be passed. value: The value of the setting. Returns: The response. See :py:meth:`send_command` for details. """ if not setting_id and not name: raise RequiredArgument( function=self.modify_user_setting.__name__, argument="setting_id or name argument", ) if value is None: raise RequiredArgument( function=self.modify_user_setting.__name__, argument="value argument", ) cmd = XmlCommand("modify_setting") if setting_id: cmd.set_attribute("setting_id", setting_id) else: cmd.add_element("name", name) cmd.add_element("value", to_base64(value)) return self._send_xml_command(cmd)