def modify_credential( self, credential_id: str, *, name: Optional[str] = None, comment: Optional[str] = None, allow_insecure: Optional[bool] = None, certificate: Optional[str] = None, key_phrase: Optional[str] = None, private_key: Optional[str] = None, login: Optional[str] = None, password: Optional[str] = None, auth_algorithm: Optional[SnmpAuthAlgorithm] = None, community: Optional[str] = None, privacy_algorithm: Optional[SnmpPrivacyAlgorithm] = None, privacy_password: Optional[str] = None, public_key: Optional[str] = None) -> Any: """Modifies an existing credential. Arguments: credential_id: UUID of the credential name: Name of the credential comment: Comment for the credential allow_insecure: Whether to allow insecure use of the credential certificate: Certificate for the credential key_phrase: Key passphrase for the private key private_key: Private key to use for login login: Username for the credential password: Password for the credential auth_algorithm: The authentication algorithm for SNMP community: The SNMP community privacy_algorithm: The privacy algorithm for SNMP privacy_password: The SNMP privacy password public_key: PGP public key in *armor* plain text format Returns: The response. See :py:meth:`send_command` for details. """ if not credential_id: raise RequiredArgument( function=self.modify_credential.__name__, argument='credential_id', ) cmd = XmlCommand("modify_credential") cmd.set_attribute("credential_id", credential_id) if comment: cmd.add_element("comment", comment) if name: cmd.add_element("name", name) if allow_insecure is not None: cmd.add_element("allow_insecure", _to_bool(allow_insecure)) if certificate: cmd.add_element("certificate", certificate) if key_phrase and private_key: _xmlkey = cmd.add_element("key") _xmlkey.add_element("phrase", key_phrase) _xmlkey.add_element("private", private_key) elif (not key_phrase and private_key) or (key_phrase and not private_key): raise RequiredArgument( function=self.modify_credential.__name__, argument='key_phrase and private_key', ) if login: cmd.add_element("login", login) if password: cmd.add_element("password", password) if auth_algorithm: if not isinstance(auth_algorithm, self.types.SnmpAuthAlgorithm): raise InvalidArgumentType( function=self.modify_credential.__name__, argument='auth_algorithm', arg_type=SnmpAuthAlgorithm.__name__, ) cmd.add_element("auth_algorithm", auth_algorithm.value) if community: cmd.add_element("community", community) if privacy_algorithm is not None or privacy_password is not None: _xmlprivacy = cmd.add_element("privacy") if privacy_algorithm is not None: if not isinstance(privacy_algorithm, self.types.SnmpPrivacyAlgorithm): raise InvalidArgumentType( function=self.modify_credential.__name__, argument='privacy_algorithm', arg_type=SnmpPrivacyAlgorithm.__name__, ) _xmlprivacy.add_element("algorithm", privacy_algorithm.value) if privacy_password is not None: _xmlprivacy.add_element("password", privacy_password) if public_key: _xmlkey = cmd.add_element("key") _xmlkey.add_element("public", public_key) return self._send_xml_command(cmd)
def modify_tag(self, tag_id: str, *, comment: Optional[str] = None, name: Optional[str] = None, value=None, active=None, resource_action: Optional[str] = None, resource_type: Optional[EntityType] = None, resource_filter: Optional[str] = None, resource_ids: Optional[List[str]] = None) -> Any: """Modifies an existing tag. Arguments: tag_id: UUID of the tag. comment: Comment to add to the tag. name: Name of the tag. value: Value of the tag. active: Whether the tag is active. resource_action: Whether to add or remove resources instead of overwriting. One of '', 'add', 'set' or 'remove'. resource_type: Type of the resources to which to attach the tag. Required if resource_filter is set. resource_filter: Filter term to select resources the tag is to be attached to. resource_ids: IDs of the resources to which to attach the tag. Returns: The response. See :py:meth:`send_command` for details. """ if not tag_id: raise RequiredArgument(function=self.modify_tag.__name__, argument='tag_id') cmd = XmlCommand("modify_tag") cmd.set_attribute("tag_id", str(tag_id)) if comment: cmd.add_element("comment", comment) if name: cmd.add_element("name", name) if value: cmd.add_element("value", value) if active is not None: cmd.add_element("active", _to_bool(active)) if resource_action or resource_filter or resource_ids or resource_type: if resource_filter and not resource_type: raise RequiredArgument(function=self.modify_tag.__name__, argument='resource_type') _xmlresources = cmd.add_element("resources") if resource_action is not None: _xmlresources.set_attribute("action", resource_action) if resource_filter is not None: _xmlresources.set_attribute("filter", resource_filter) for resource_id in resource_ids or []: _xmlresources.add_element("resource", attrs={"id": str(resource_id)}) if resource_type is not None: if not isinstance(resource_type, self.types.EntityType): raise InvalidArgumentType( function=self.modify_tag.__name__, argument="resource_type", arg_type=EntityType.__name__, ) _xmlresources.add_element("type", resource_type.value) return self._send_xml_command(cmd)
def create_target( self, name: str, *, make_unique: Optional[bool] = None, asset_hosts_filter: Optional[str] = None, hosts: Optional[List[str]] = None, comment: Optional[str] = None, exclude_hosts: Optional[List[str]] = None, ssh_credential_id: Optional[str] = None, ssh_credential_port: Optional[int] = None, smb_credential_id: Optional[str] = None, esxi_credential_id: Optional[str] = None, snmp_credential_id: Optional[str] = None, alive_test: Optional[AliveTest] = None, reverse_lookup_only: Optional[bool] = None, reverse_lookup_unify: Optional[bool] = None, port_range: Optional[str] = None, port_list_id: Optional[str] = None, ) -> Any: """Create a new target Arguments: name: Name of the target make_unique: Deprecated. Will be ignored. asset_hosts_filter: Filter to select target host from assets hosts hosts: List of hosts addresses to scan exclude_hosts: List of hosts addresses to exclude from scan comment: Comment for the target ssh_credential_id: UUID of a ssh credential to use on target ssh_credential_port: The port to use for ssh credential smb_credential_id: UUID of a smb credential to use on target snmp_credential_id: UUID of a snmp credential to use on target esxi_credential_id: UUID of a esxi credential to use on target alive_test: Which alive test to use reverse_lookup_only: Whether to scan only hosts that have names reverse_lookup_unify: Whether to scan only one IP when multiple IPs have the same name. port_range: Port range for the target port_list_id: UUID of the port list to use on target Returns: The response. See :py:meth:`send_command` for details. """ cmd = XmlCommand("create_target") _xmlname = cmd.add_element("name", name) if make_unique is not None: warnings.warn( 'create_target make_unique argument is deprecated ' 'and will be ignored.', DeprecationWarning, ) if not name: raise RequiredArgument(function=self.create_target.__name__, argument='name') if asset_hosts_filter: cmd.add_element("asset_hosts", attrs={"filter": str(asset_hosts_filter)}) elif hosts: cmd.add_element("hosts", _to_comma_list(hosts)) else: raise RequiredArgument( function=self.create_target.__name__, argument='hosts or asset_hosts_filter', ) if comment: cmd.add_element("comment", comment) if exclude_hosts: cmd.add_element("exclude_hosts", _to_comma_list(exclude_hosts)) if ssh_credential_id: _xmlssh = cmd.add_element("ssh_credential", attrs={"id": ssh_credential_id}) if ssh_credential_port: _xmlssh.add_element("port", str(ssh_credential_port)) if smb_credential_id: cmd.add_element("smb_credential", attrs={"id": smb_credential_id}) if esxi_credential_id: cmd.add_element("esxi_credential", attrs={"id": esxi_credential_id}) if snmp_credential_id: cmd.add_element("snmp_credential", attrs={"id": snmp_credential_id}) if alive_test: if not isinstance(alive_test, AliveTest): raise InvalidArgumentType( function=self.create_target.__name__, argument='alive_test', arg_type=AliveTest.__name__, ) cmd.add_element("alive_tests", alive_test.value) if reverse_lookup_only is not None: cmd.add_element("reverse_lookup_only", _to_bool(reverse_lookup_only)) if reverse_lookup_unify is not None: cmd.add_element("reverse_lookup_unify", _to_bool(reverse_lookup_unify)) # since 20.08 one of port_range or port_list_id is required! if not port_range and not port_list_id: raise RequiredArgument( function=self.create_target.__name__, argument='port_range or port_list_id', ) if port_range: cmd.add_element("port_range", port_range) if port_list_id: cmd.add_element("port_list", attrs={"id": port_list_id}) return self._send_xml_command(cmd)
def create_credential( self, name: str, credential_type: CredentialType, *, comment: Optional[str] = None, allow_insecure: Optional[bool] = None, certificate: Optional[str] = None, key_phrase: Optional[str] = None, private_key: Optional[str] = None, login: Optional[str] = None, password: Optional[str] = None, auth_algorithm: Optional[SnmpAuthAlgorithm] = None, community: Optional[str] = None, privacy_algorithm: Optional[SnmpPrivacyAlgorithm] = None, privacy_password: Optional[str] = None, public_key: Optional[str] = None, ) -> Any: """Create a new credential Create a new credential e.g. to be used in the method of an alert. Currently the following credential types are supported: - Username + Password - Username + SSH-Key - Client Certificates - SNMPv1 or SNMPv2c protocol - S/MIME Certificate - OpenPGP Key - Password only Arguments: name: Name of the new credential credential_type: The credential type. comment: Comment for the credential allow_insecure: Whether to allow insecure use of the credential certificate: Certificate for the credential. Required for client-certificate and smime credential types. key_phrase: Key passphrase for the private key. Used for the username+ssh-key credential type. private_key: Private key to use for login. Required for usk credential type. Also used for the cc credential type. The supported key types (dsa, rsa, ecdsa, ...) and formats (PEM, PKC#12, OpenSSL, ...) depend on your installed GnuTLS version. login: Username for the credential. Required for username+password, username+ssh-key and snmp credential type. password: Password for the credential. Used for username+password and snmp credential types. community: The SNMP community auth_algorithm: The SNMP authentication algorithm. Required for snmp credential type. privacy_algorithm: The SNMP privacy algorithm privacy_password: The SNMP privacy password public_key: PGP public key in *armor* plain text format. Required for pgp credential type. Examples: Creating a Username + Password credential .. code-block:: python gmp.create_credential( name='UP Credential', credential_type=CredentialType.USERNAME_PASSWORD, login='******', password='******', ) Creating a Username + SSH Key credential .. code-block:: python with open('path/to/private-ssh-key') as f: key = f.read() gmp.create_credential( name='USK Credential', credential_type=CredentialType.USERNAME_SSH_KEY, login='******', key_phrase='foobar', private_key=key, ) Creating a PGP credential .. note:: A compatible public pgp key file can be exported with GnuPG via :: $ gpg --armor --export [email protected] > alice.asc .. code-block:: python with open('path/to/pgp.key.asc') as f: key = f.read() gmp.create_credential( name='PGP Credential', credential_type=CredentialType.PGP_ENCRYPTION_KEY, public_key=key, ) Creating a S/MIME credential .. code-block:: python with open('path/to/smime-cert') as f: cert = f.read() gmp.create_credential( name='SMIME Credential', credential_type=CredentialType.SMIME_CERTIFICATE, certificate=cert, ) Creating a Password-Only credential .. code-block:: python gmp.create_credential( name='Password-Only Credential', credential_type=CredentialType.PASSWORD_ONLY, password='******', ) Returns: The response. See :py:meth:`send_command` for details. """ if not name: raise RequiredArgument(function=self.create_credential.__name__, argument='name') if not isinstance(credential_type, self.types.CredentialType): raise InvalidArgumentType( function=self.create_credential.__name__, argument='credential_type', arg_type=CredentialType.__name__, ) cmd = XmlCommand("create_credential") cmd.add_element("name", name) cmd.add_element("type", credential_type.value) if comment: cmd.add_element("comment", comment) if allow_insecure is not None: cmd.add_element("allow_insecure", _to_bool(allow_insecure)) if (credential_type == CredentialType.CLIENT_CERTIFICATE or credential_type == CredentialType.SMIME_CERTIFICATE): if not certificate: raise RequiredArgument( function=self.create_credential.__name__, argument='certificate', ) cmd.add_element("certificate", certificate) if (credential_type == CredentialType.USERNAME_PASSWORD or credential_type == CredentialType.USERNAME_SSH_KEY or credential_type == CredentialType.SNMP): if not login: raise RequiredArgument( function=self.create_credential.__name__, argument='login') cmd.add_element("login", login) if credential_type == CredentialType.PASSWORD_ONLY and not password: raise RequiredArgument(function=self.create_credential.__name__, argument='password') if (credential_type == CredentialType.USERNAME_PASSWORD or credential_type == CredentialType.SNMP or credential_type == CredentialType.PASSWORD_ONLY) and password: cmd.add_element("password", password) if credential_type == CredentialType.USERNAME_SSH_KEY: if not private_key: raise RequiredArgument( function=self.create_credential.__name__, argument='private_key', ) _xmlkey = cmd.add_element("key") _xmlkey.add_element("private", private_key) if key_phrase: _xmlkey.add_element("phrase", key_phrase) if credential_type == CredentialType.CLIENT_CERTIFICATE and private_key: _xmlkey = cmd.add_element("key") _xmlkey.add_element("private", private_key) if credential_type == CredentialType.SNMP: if not isinstance(auth_algorithm, self.types.SnmpAuthAlgorithm): raise InvalidArgumentType( function=self.create_credential.__name__, argument='auth_algorithm', arg_type=SnmpAuthAlgorithm.__name__, ) cmd.add_element("auth_algorithm", auth_algorithm.value) if community: cmd.add_element("community", community) if privacy_algorithm is not None or privacy_password: _xmlprivacy = cmd.add_element("privacy") if privacy_algorithm is not None: if not isinstance(privacy_algorithm, self.types.SnmpPrivacyAlgorithm): raise InvalidArgumentType( function=self.create_credential.__name__, argument='privacy_algorithm', arg_type=SnmpPrivacyAlgorithm.__name__, ) _xmlprivacy.add_element("algorithm", privacy_algorithm.value) if privacy_password: _xmlprivacy.add_element("password", privacy_password) if credential_type == CredentialType.PGP_ENCRYPTION_KEY: if not public_key: raise RequiredArgument( function=self.create_credential.__name__, argument='public_key', ) _xmlkey = cmd.add_element("key") _xmlkey.add_element("public", public_key) return self._send_xml_command(cmd)
def __create_task( self, name: str, config_id: str, target_id: str, scanner_id: str, usage_type: UsageType, function: str, *, alterable: Optional[bool] = None, hosts_ordering: Optional[HostsOrdering] = None, schedule_id: Optional[str] = None, alert_ids: Optional[List[str]] = None, comment: Optional[str] = None, schedule_periods: Optional[int] = None, observers: Optional[List[str]] = None, preferences: Optional[dict] = None ) -> Any: if not name: raise RequiredArgument(function=function, argument='name') if not config_id: raise RequiredArgument(function=function, argument='config_id') if not target_id: raise RequiredArgument(function=function, argument='target_id') if not scanner_id: raise RequiredArgument(function=function, argument='scanner_id') # don't allow to create a container task with create_task if target_id == '0': raise InvalidArgument(function=function, argument='target_id') cmd = XmlCommand("create_task") cmd.add_element("name", name) cmd.add_element("usage_type", usage_type.value) cmd.add_element("config", attrs={"id": config_id}) cmd.add_element("target", attrs={"id": target_id}) cmd.add_element("scanner", attrs={"id": scanner_id}) if comment: cmd.add_element("comment", comment) if alterable is not None: cmd.add_element("alterable", _to_bool(alterable)) if hosts_ordering: if not isinstance(hosts_ordering, self.types.HostsOrdering): raise InvalidArgumentType( function=function, argument='hosts_ordering', arg_type=HostsOrdering.__name__, ) cmd.add_element("hosts_ordering", hosts_ordering.value) if alert_ids: if isinstance(alert_ids, str): deprecation( "Please pass a list as alert_ids parameter to {}. " "Passing a string is deprecated and will be removed in " "future.".format(function) ) # if a single id is given as a string wrap it into a list alert_ids = [alert_ids] if _is_list_like(alert_ids): # parse all given alert id's for alert in alert_ids: cmd.add_element("alert", attrs={"id": str(alert)}) if schedule_id: cmd.add_element("schedule", attrs={"id": schedule_id}) if schedule_periods is not None: if ( not isinstance(schedule_periods, numbers.Integral) or schedule_periods < 0 ): raise InvalidArgument( "schedule_periods must be an integer greater or equal " "than 0" ) cmd.add_element("schedule_periods", str(schedule_periods)) if observers is not None: if not _is_list_like(observers): raise InvalidArgumentType( function=function, argument='observers', arg_type='list' ) # gvmd splits by comma and space # gvmd tries to lookup each value as user name and afterwards as # user id. So both user name and user id are possible cmd.add_element("observers", _to_comma_list(observers)) if preferences is not None: if not isinstance(preferences, collections.abc.Mapping): raise InvalidArgumentType( function=function, argument='preferences', arg_type=collections.abc.Mapping.__name__, ) _xmlprefs = cmd.add_element("preferences") for pref_name, pref_value in preferences.items(): _xmlpref = _xmlprefs.add_element("preference") _xmlpref.add_element("scanner_name", pref_name) _xmlpref.add_element("value", str(pref_value)) return self._send_xml_command(cmd)
def modify_user( self, user_id: str = None, *, name: Optional[str] = None, comment: Optional[str] = None, password: Optional[str] = None, auth_source: Optional[UserAuthType] = None, role_ids: Optional[List[str]] = None, hosts: Optional[List[str]] = None, hosts_allow: Optional[bool] = False, ifaces: Optional[List[str]] = None, ifaces_allow: Optional[bool] = False, group_ids: Optional[List[str]] = None, ) -> Any: """Modifies an existing user. Most of the fields need to be supplied for changing a single field even if no change is wanted for those. Else empty values are inserted for the missing fields instead. Arguments: user_id: UUID of the user to be modified. name: The new name for the user. comment: Comment on the user. password: The password for the user. auth_source: Source allowed for authentication for this user. roles_id: List of roles UUIDs for the user. hosts: User access rules: List of hosts. hosts_allow: Defines how the hosts list is to be interpreted. If False (default) the list is treated as a deny list. All hosts are allowed by default except those provided by the hosts parameter. If True the list is treated as a allow list. All hosts are denied by default except those provided by the hosts parameter. ifaces: User access rules: List of ifaces. ifaces_allow: Defines how the ifaces list is to be interpreted. If False (default) the list is treated as a deny list. All ifaces are allowed by default except those provided by the ifaces parameter. If True the list is treated as a allow list. All ifaces are denied by default except those provided by the ifaces parameter. group_ids: List of group UUIDs for the user. Returns: The response. See :py:meth:`send_command` for details. """ if not user_id: raise RequiredArgument(function=self.modify_user.__name__, argument='user_id') cmd = XmlCommand("modify_user") if user_id: cmd.set_attribute("user_id", user_id) if name: cmd.add_element("new_name", name) if role_ids: for role in role_ids: cmd.add_element("role", attrs={"id": role}) 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 comment: cmd.add_element("comment", comment) if password: cmd.add_element("password", password) if auth_source: _xmlauthsrc = cmd.add_element("sources") _xmlauthsrc.add_element("source", auth_source.value) if group_ids: _xmlgroups = cmd.add_element("groups") for group_id in group_ids: _xmlgroups.add_element("group", attrs={"id": group_id}) return self._send_xml_command(cmd)
def modify_target( self, target_id: str, *, name: Optional[str] = None, comment: Optional[str] = None, hosts: Optional[List[str]] = None, exclude_hosts: Optional[List[str]] = None, ssh_credential_id: Optional[str] = None, ssh_credential_port: Optional[bool] = None, smb_credential_id: Optional[str] = None, esxi_credential_id: Optional[str] = None, snmp_credential_id: Optional[str] = None, alive_test: Optional[AliveTest] = None, allow_simultaneous_ips: Optional[bool] = None, reverse_lookup_only: Optional[bool] = None, reverse_lookup_unify: Optional[bool] = None, port_list_id: Optional[str] = None, ) -> Any: """Modifies an existing target. Arguments: target_id: ID of target to modify. comment: Comment on target. name: Name of target. hosts: List of target hosts. exclude_hosts: A list of hosts to exclude. ssh_credential_id: UUID of SSH credential to use on target. ssh_credential_port: The port to use for ssh credential smb_credential_id: UUID of SMB credential to use on target. esxi_credential_id: UUID of ESXi credential to use on target. snmp_credential_id: UUID of SNMP credential to use on target. port_list_id: UUID of port list describing ports to scan. alive_test: Which alive tests to use. allow_simultaneous_ips: Whether to scan multiple IPs of the same host simultaneously reverse_lookup_only: Whether to scan only hosts that have names. reverse_lookup_unify: Whether to scan only one IP when multiple IPs have the same name. Returns: The response. See :py:meth:`send_command` for details. """ if not target_id: raise RequiredArgument(function=self.modify_target.__name__, argument='target_id') cmd = XmlCommand("modify_target") cmd.set_attribute("target_id", target_id) if comment: cmd.add_element("comment", comment) if name: cmd.add_element("name", name) if hosts: cmd.add_element("hosts", _to_comma_list(hosts)) if exclude_hosts is None: exclude_hosts = [''] if exclude_hosts: cmd.add_element("exclude_hosts", _to_comma_list(exclude_hosts)) if alive_test: if not isinstance(alive_test, AliveTest): raise InvalidArgumentType( function=self.modify_target.__name__, argument='alive_test', arg_type=AliveTest.__name__, ) cmd.add_element("alive_tests", alive_test.value) if ssh_credential_id: _xmlssh = cmd.add_element("ssh_credential", attrs={"id": ssh_credential_id}) if ssh_credential_port: _xmlssh.add_element("port", str(ssh_credential_port)) if smb_credential_id: cmd.add_element("smb_credential", attrs={"id": smb_credential_id}) if esxi_credential_id: cmd.add_element("esxi_credential", attrs={"id": esxi_credential_id}) if snmp_credential_id: cmd.add_element("snmp_credential", attrs={"id": snmp_credential_id}) if allow_simultaneous_ips is not None: cmd.add_element( "allow_simultaneous_ips", _to_bool(allow_simultaneous_ips), ) if reverse_lookup_only is not None: cmd.add_element("reverse_lookup_only", _to_bool(reverse_lookup_only)) if reverse_lookup_unify is not None: cmd.add_element("reverse_lookup_unify", _to_bool(reverse_lookup_unify)) if port_list_id: cmd.add_element("port_list", attrs={"id": port_list_id}) return self._send_xml_command(cmd)