Skip to content

Commit d00f702

Browse files
bjoernricksgreenbonebot
authored andcommitted
Add: Draft new implementation for GMP protocol classes base on the core module
Use the core module to re-implement the current GMP protocol classes.
1 parent a65c046 commit d00f702

File tree

4 files changed

+238
-31
lines changed

4 files changed

+238
-31
lines changed

gvm/protocols/gmp/__init__.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# SPDX-FileCopyrightText: 2024 Greenbone AG
2+
#
3+
# SPDX-License-Identifier: GPL-3.0-or-later
4+
5+
from ._gmp import GMP
6+
7+
Gmp = GMP # for backwards compatibility
8+
9+
__all__ = (
10+
"GMP",
11+
"Gmp",
12+
)

gvm/protocols/gmp.py renamed to gvm/protocols/gmp/_gmp.py

Lines changed: 22 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,23 @@
11
# SPDX-FileCopyrightText: 2019-2024 Greenbone AG
22
#
33
# SPDX-License-Identifier: GPL-3.0-or-later
4-
#
54

6-
"""
7-
Module for communication with gvmd
8-
"""
95
from types import TracebackType
10-
from typing import Any, Callable, Optional, Type, Union
6+
from typing import Callable, Optional, Type, Union
117

8+
from gvm.connections import GvmConnection
129
from gvm.errors import GvmError
13-
from gvm.protocols.base import GvmConnection, GvmProtocol
14-
from gvm.protocols.gmpv208 import Gmp as Gmpv208
15-
from gvm.protocols.gmpv214 import Gmp as Gmpv214
16-
from gvm.protocols.gmpv224 import Gmp as Gmpv224
17-
from gvm.protocols.gmpv225 import Gmp as Gmpv225
18-
from gvm.transforms import EtreeCheckCommandTransform
19-
from gvm.xml import XmlCommand
2010

21-
SUPPORTED_GMP_VERSIONS = Union[ # pylint: disable=invalid-name
22-
Gmpv208, Gmpv214, Gmpv224, Gmpv225
23-
]
11+
from .._protocol import GvmProtocol, T, str_transform
12+
from ._gmp224 import GMPv224
13+
from ._gmp225 import GMPv225
14+
from .core import Response
15+
from .core.requests import Version
16+
17+
SUPPORTED_GMP_VERSIONS = Union[GMPv224, GMPv225]
2418

2519

26-
class Gmp(GvmProtocol):
20+
class GMP(GvmProtocol[T]):
2721
"""Dynamically select supported GMP protocol of the remote manager daemon.
2822
2923
Must be used as a `Context Manager
@@ -59,19 +53,18 @@ def __init__(
5953
self,
6054
connection: GvmConnection,
6155
*,
62-
transform: Optional[Callable[[str], Any]] = None,
56+
transform: Callable[[Response], T] = str_transform, # type: ignore[assignment] # this should work with mypy 1.9.0 without an ignore
6357
):
64-
super().__init__(connection, transform=EtreeCheckCommandTransform())
65-
self._gmp_transform = transform
58+
super().__init__(connection, transform=transform)
6659

6760
def determine_remote_gmp_version(self) -> str:
6861
"""Determine the supported GMP version of the remote daemon"""
6962
self.connect()
70-
resp = self._send_xml_command(XmlCommand("get_version"))
63+
resp = self._send_command(Version.get_version())
7164
self.disconnect()
7265

73-
version_el = resp.find("version")
74-
if version_el is None:
66+
version_el = resp.xml().find("version")
67+
if version_el is None or not version_el.text:
7568
raise GvmError(
7669
"Invalid response from manager daemon while requesting the "
7770
"version information."
@@ -86,21 +79,19 @@ def determine_supported_gmp(self) -> SUPPORTED_GMP_VERSIONS:
8679
version_str = self.determine_remote_gmp_version().split(".", 1)
8780
major_version = int(version_str[0])
8881
minor_version = int(version_str[1])
89-
if major_version == 20:
90-
gmp_class = Gmpv208
91-
elif major_version == 21 and minor_version == 4:
92-
gmp_class = Gmpv214
93-
elif major_version == 22 and minor_version == 4:
94-
gmp_class = Gmpv224
82+
# if major_version == 22 and minor_version == 4:
83+
# gmp_class = Gmpv224
84+
if major_version == 22 and minor_version == 4:
85+
gmp_class = GMPv224
9586
elif major_version == 22 and minor_version == 5:
96-
gmp_class = Gmpv225
87+
gmp_class = GMPv225
9788
else:
9889
raise GvmError(
9990
"Remote manager daemon uses an unsupported version of GMP. "
10091
f"The GMP version was {major_version}.{minor_version}"
10192
)
10293

103-
return gmp_class(self._connection, transform=self._gmp_transform)
94+
return gmp_class(self._connection, transform=self._transform_callable)
10495

10596
def __enter__(self):
10697
self._gmp = self.determine_supported_gmp()
@@ -114,6 +105,6 @@ def __exit__(
114105
exc_type: Optional[Type[BaseException]],
115106
exc_value: Optional[BaseException],
116107
traceback: Optional[TracebackType],
117-
) -> Any:
108+
) -> None:
118109
self._gmp.disconnect()
119110
self._gmp = None

gvm/protocols/gmp/_gmp224.py

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
# SPDX-FileCopyrightText: 2024 Greenbone AG
2+
#
3+
# SPDX-License-Identifier: GPL-3.0-or-later
4+
5+
from typing import Optional, Union
6+
7+
from .._protocol import GvmProtocol, T
8+
from .core.requests import (
9+
Authentication,
10+
PortList,
11+
PortRangeType,
12+
Version,
13+
)
14+
15+
16+
class GMPv224(GvmProtocol[T]):
17+
_authenticated = False
18+
19+
def is_authenticated(self) -> bool:
20+
"""Checks if the user is authenticated
21+
22+
If the user is authenticated privileged GMP commands like get_tasks
23+
may be send to gvmd.
24+
25+
Returns:
26+
bool: True if an authenticated connection to gvmd has been
27+
established.
28+
"""
29+
return self._authenticated
30+
31+
def authenticate(self, username: str, password: str) -> T:
32+
"""Authenticate to gvmd.
33+
34+
The generated authenticate command will be send to server.
35+
Afterwards the response is read, transformed and returned.
36+
37+
Arguments:
38+
username: Username
39+
password: Password
40+
"""
41+
response = self._send_command(
42+
Authentication.authenticate(username=username, password=password)
43+
)
44+
45+
if response.is_success:
46+
self._authenticated = True
47+
48+
return self._transform(response)
49+
50+
def describe_auth(self) -> T:
51+
"""Describe authentication methods
52+
53+
Returns a list of all used authentication methods if such a list is
54+
available.
55+
56+
Returns:
57+
The response. See :py:meth:`send_command` for details.
58+
"""
59+
return self._send_and_transform_command(Authentication.describe_auth())
60+
61+
def modify_auth(
62+
self, group_name: str, auth_conf_settings: dict[str, str]
63+
) -> T:
64+
"""Modifies an existing auth.
65+
66+
Arguments:
67+
group_name: Name of the group to be modified.
68+
auth_conf_settings: The new auth config.
69+
"""
70+
return self._send_and_transform_command(
71+
Authentication.modify_auth(group_name, auth_conf_settings)
72+
)
73+
74+
def get_version(self) -> T:
75+
return self._send_and_transform_command(Version.get_version())
76+
77+
def clone_port_list(self, port_list_id: str) -> T:
78+
return self._send_and_transform_command(
79+
PortList.clone_port_list(port_list_id)
80+
)
81+
82+
def create_port_list(
83+
self, name: str, port_range: str, *, comment: Optional[str] = None
84+
) -> T:
85+
return self._send_and_transform_command(
86+
PortList.create_port_list(name, port_range, comment=comment)
87+
)
88+
89+
def create_port_range(
90+
self,
91+
port_list_id: str,
92+
start: int,
93+
end: int,
94+
port_range_type: Union[str, PortRangeType],
95+
*,
96+
comment: Optional[str] = None,
97+
) -> T:
98+
return self._send_and_transform_command(
99+
PortList.create_port_range(
100+
port_list_id, start, end, port_range_type, comment=comment
101+
)
102+
)
103+
104+
def delete_port_list(
105+
self, port_list_id: str, *, ultimate: bool = False
106+
) -> T:
107+
return self._send_and_transform_command(
108+
PortList.delete_port_list(port_list_id, ultimate=ultimate)
109+
)
110+
111+
def delete_port_range(self, port_range_id: str) -> T:
112+
return self._send_and_transform_command(
113+
PortList.delete_port_range(port_range_id)
114+
)
115+
116+
def get_port_lists(
117+
self,
118+
*,
119+
filter_string: Optional[str] = None,
120+
filter_id: Optional[str] = None,
121+
details: Optional[bool] = None,
122+
targets: Optional[bool] = None,
123+
trash: Optional[bool] = None,
124+
) -> T:
125+
return self._send_and_transform_command(
126+
PortList.get_port_lists(
127+
filter_string=filter_string,
128+
filter_id=filter_id,
129+
details=details,
130+
targets=targets,
131+
trash=trash,
132+
)
133+
)
134+
135+
def get_port_list(self, port_list_id: str) -> T:
136+
return self._send_and_transform_command(
137+
PortList.get_port_list(port_list_id)
138+
)
139+
140+
def modify_port_list(
141+
self,
142+
port_list_id: str,
143+
*,
144+
comment: Optional[str] = None,
145+
name: Optional[str] = None,
146+
) -> T:
147+
return self._send_and_transform_command(
148+
PortList.modify_port_list(port_list_id, comment=comment, name=name)
149+
)

gvm/protocols/gmp/_gmp225.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# SPDX-FileCopyrightText: 2024 Greenbone AG
2+
#
3+
# SPDX-License-Identifier: GPL-3.0-or-later
4+
5+
from typing import Optional
6+
7+
from .._protocol import T
8+
from ._gmp224 import GMPv224
9+
from .core.requests import (
10+
ResourceNames,
11+
ResourceType,
12+
)
13+
14+
15+
class GMPv225(GMPv224[T]):
16+
def get_resource_names(
17+
self,
18+
resource_type: ResourceType,
19+
*,
20+
filter_string: Optional[str] = None,
21+
) -> T:
22+
"""Request a list of resource names and IDs
23+
24+
Arguments:
25+
resource_type: Type must be either ALERT, CERT_BUND_ADV,
26+
CONFIG, CPE, CREDENTIAL, CVE, DFN_CERT_ADV, FILTER,
27+
GROUP, HOST, NOTE, NVT, OS, OVERRIDE, PERMISSION,
28+
PORT_LIST, REPORT_FORMAT, REPORT, RESULT, ROLE,
29+
SCANNER, SCHEDULE, TARGET, TASK, TLS_CERTIFICATE
30+
or USER
31+
filter_string: Filter term to use for the query
32+
"""
33+
return self._send_and_transform_command(
34+
ResourceNames.get_resource_names(
35+
resource_type, filter_string=filter_string
36+
)
37+
)
38+
39+
def get_resource_name(
40+
self, resource_id: str, resource_type: ResourceType
41+
) -> T:
42+
"""Request a single resource name
43+
44+
Arguments:
45+
resource_id: ID of an existing resource
46+
resource_type: Type must be either ALERT, CERT_BUND_ADV,
47+
CONFIG, CPE, CREDENTIAL, CVE, DFN_CERT_ADV, FILTER,
48+
GROUP, HOST, NOTE, NVT, OS, OVERRIDE, PERMISSION,
49+
PORT_LIST, REPORT_FORMAT, REPORT, RESULT, ROLE,
50+
SCANNER, SCHEDULE, TARGET, TASK, TLS_CERTIFICATE
51+
or USER
52+
"""
53+
return self._send_and_transform_command(
54+
ResourceNames.get_resource_name(resource_id, resource_type)
55+
)

0 commit comments

Comments
 (0)