1# -*- coding: utf-8 -*- 2# Copyright (C) 2021 Greenbone Networks GmbH 3# 4# SPDX-License-Identifier: GPL-3.0-or-later 5# 6# This program is free software: you can redistribute it and/or modify 7# it under the terms of the GNU General Public License as published by 8# the Free Software Foundation, either version 3 of the License, or 9# (at your option) any later version. 10# 11# This program is distributed in the hope that it will be useful, 12# but WITHOUT ANY WARRANTY; without even the implied warranty of 13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14# GNU General Public License for more details. 15# 16# You should have received a copy of the GNU General Public License 17# along with this program. If not, see <http://www.gnu.org/licenses/>. 18 19# pylint: disable=arguments-differ, unused-import 20 21from typing import Any, List, Optional 22 23from gvm.errors import RequiredArgument, InvalidArgumentType 24from gvm.protocols.gmpv208.entities.targets import ( 25 TargetsMixin as Gmp208TargetsMixin, 26 AliveTest, 27) 28from gvm.utils import to_bool, to_comma_list 29from gvm.xml import XmlCommand 30 31 32class TargetsMixin(Gmp208TargetsMixin): 33 def create_target( 34 self, 35 name: str, 36 *, 37 asset_hosts_filter: Optional[str] = None, 38 hosts: Optional[List[str]] = None, 39 comment: Optional[str] = None, 40 exclude_hosts: Optional[List[str]] = None, 41 ssh_credential_id: Optional[str] = None, 42 ssh_credential_port: Optional[int] = None, 43 smb_credential_id: Optional[str] = None, 44 esxi_credential_id: Optional[str] = None, 45 snmp_credential_id: Optional[str] = None, 46 alive_test: Optional[AliveTest] = None, 47 allow_simultaneous_ips: Optional[bool] = None, 48 reverse_lookup_only: Optional[bool] = None, 49 reverse_lookup_unify: Optional[bool] = None, 50 port_range: Optional[str] = None, 51 port_list_id: Optional[str] = None, 52 ) -> Any: 53 """Create a new target 54 55 Arguments: 56 name: Name of the target 57 asset_hosts_filter: Filter to select target host from assets hosts 58 hosts: List of hosts addresses to scan 59 exclude_hosts: List of hosts addresses to exclude from scan 60 comment: Comment for the target 61 ssh_credential_id: UUID of a ssh credential to use on target 62 ssh_credential_port: The port to use for ssh credential 63 smb_credential_id: UUID of a smb credential to use on target 64 snmp_credential_id: UUID of a snmp credential to use on target 65 esxi_credential_id: UUID of a esxi credential to use on target 66 alive_test: Which alive test to use 67 allow_simultaneous_ips: Whether to scan multiple IPs of the 68 same host simultaneously 69 reverse_lookup_only: Whether to scan only hosts that have names 70 reverse_lookup_unify: Whether to scan only one IP when multiple IPs 71 have the same name. 72 port_range: Port range for the target 73 port_list_id: UUID of the port list to use on target 74 75 Returns: 76 The response. See :py:meth:`send_command` for details. 77 """ 78 if not name: 79 raise RequiredArgument( 80 function=self.create_target.__name__, argument='name' 81 ) 82 83 cmd = XmlCommand("create_target") 84 cmd.add_element("name", name) 85 86 if asset_hosts_filter: 87 cmd.add_element( 88 "asset_hosts", attrs={"filter": str(asset_hosts_filter)} 89 ) 90 elif hosts: 91 cmd.add_element("hosts", to_comma_list(hosts)) 92 else: 93 raise RequiredArgument( 94 function=self.create_target.__name__, 95 argument='hosts or asset_hosts_filter', 96 ) 97 98 if comment: 99 cmd.add_element("comment", comment) 100 101 if exclude_hosts: 102 cmd.add_element("exclude_hosts", to_comma_list(exclude_hosts)) 103 104 if ssh_credential_id: 105 _xmlssh = cmd.add_element( 106 "ssh_credential", attrs={"id": ssh_credential_id} 107 ) 108 if ssh_credential_port: 109 _xmlssh.add_element("port", str(ssh_credential_port)) 110 111 if smb_credential_id: 112 cmd.add_element("smb_credential", attrs={"id": smb_credential_id}) 113 114 if esxi_credential_id: 115 cmd.add_element("esxi_credential", attrs={"id": esxi_credential_id}) 116 117 if snmp_credential_id: 118 cmd.add_element("snmp_credential", attrs={"id": snmp_credential_id}) 119 120 if alive_test: 121 if not isinstance(alive_test, AliveTest): 122 raise InvalidArgumentType( 123 function=self.create_target.__name__, 124 argument='alive_test', 125 arg_type=AliveTest.__name__, 126 ) 127 128 cmd.add_element("alive_tests", alive_test.value) 129 130 if allow_simultaneous_ips is not None: 131 cmd.add_element( 132 "allow_simultaneous_ips", to_bool(allow_simultaneous_ips) 133 ) 134 135 if reverse_lookup_only is not None: 136 cmd.add_element("reverse_lookup_only", to_bool(reverse_lookup_only)) 137 138 if reverse_lookup_unify is not None: 139 cmd.add_element( 140 "reverse_lookup_unify", to_bool(reverse_lookup_unify) 141 ) 142 143 if port_range: 144 cmd.add_element("port_range", port_range) 145 146 if port_list_id: 147 cmd.add_element("port_list", attrs={"id": port_list_id}) 148 149 return self._send_xml_command(cmd) 150 151 def modify_target( 152 self, 153 target_id: str, 154 *, 155 name: Optional[str] = None, 156 comment: Optional[str] = None, 157 hosts: Optional[List[str]] = None, 158 exclude_hosts: Optional[List[str]] = None, 159 ssh_credential_id: Optional[str] = None, 160 ssh_credential_port: Optional[bool] = None, 161 smb_credential_id: Optional[str] = None, 162 esxi_credential_id: Optional[str] = None, 163 snmp_credential_id: Optional[str] = None, 164 alive_test: Optional[AliveTest] = None, 165 allow_simultaneous_ips: Optional[bool] = None, 166 reverse_lookup_only: Optional[bool] = None, 167 reverse_lookup_unify: Optional[bool] = None, 168 port_list_id: Optional[str] = None, 169 ) -> Any: 170 """Modifies an existing target. 171 172 Arguments: 173 target_id: ID of target to modify. 174 comment: Comment on target. 175 name: Name of target. 176 hosts: List of target hosts. 177 exclude_hosts: A list of hosts to exclude. 178 ssh_credential_id: UUID of SSH credential to use on target. 179 ssh_credential_port: The port to use for ssh credential 180 smb_credential_id: UUID of SMB credential to use on target. 181 esxi_credential_id: UUID of ESXi credential to use on target. 182 snmp_credential_id: UUID of SNMP credential to use on target. 183 port_list_id: UUID of port list describing ports to scan. 184 alive_test: Which alive tests to use. 185 allow_simultaneous_ips: Whether to scan multiple IPs of the 186 same host simultaneously 187 reverse_lookup_only: Whether to scan only hosts that have names. 188 reverse_lookup_unify: Whether to scan only one IP when multiple IPs 189 have the same name. 190 191 Returns: 192 The response. See :py:meth:`send_command` for details. 193 """ 194 if not target_id: 195 raise RequiredArgument( 196 function=self.modify_target.__name__, argument='target_id' 197 ) 198 199 cmd = XmlCommand("modify_target") 200 cmd.set_attribute("target_id", target_id) 201 202 if comment: 203 cmd.add_element("comment", comment) 204 205 if name: 206 cmd.add_element("name", name) 207 208 if hosts: 209 cmd.add_element("hosts", to_comma_list(hosts)) 210 if exclude_hosts is None: 211 exclude_hosts = [''] 212 213 if exclude_hosts: 214 cmd.add_element("exclude_hosts", to_comma_list(exclude_hosts)) 215 216 if alive_test: 217 if not isinstance(alive_test, AliveTest): 218 raise InvalidArgumentType( 219 function=self.modify_target.__name__, 220 argument='alive_test', 221 arg_type=AliveTest.__name__, 222 ) 223 cmd.add_element("alive_tests", alive_test.value) 224 225 if ssh_credential_id: 226 _xmlssh = cmd.add_element( 227 "ssh_credential", attrs={"id": ssh_credential_id} 228 ) 229 230 if ssh_credential_port: 231 _xmlssh.add_element("port", str(ssh_credential_port)) 232 233 if smb_credential_id: 234 cmd.add_element("smb_credential", attrs={"id": smb_credential_id}) 235 236 if esxi_credential_id: 237 cmd.add_element("esxi_credential", attrs={"id": esxi_credential_id}) 238 239 if snmp_credential_id: 240 cmd.add_element("snmp_credential", attrs={"id": snmp_credential_id}) 241 242 if allow_simultaneous_ips is not None: 243 cmd.add_element( 244 "allow_simultaneous_ips", to_bool(allow_simultaneous_ips) 245 ) 246 247 if reverse_lookup_only is not None: 248 cmd.add_element("reverse_lookup_only", to_bool(reverse_lookup_only)) 249 250 if reverse_lookup_unify is not None: 251 cmd.add_element( 252 "reverse_lookup_unify", to_bool(reverse_lookup_unify) 253 ) 254 255 if port_list_id: 256 cmd.add_element("port_list", attrs={"id": port_list_id}) 257 258 return self._send_xml_command(cmd) 259