diff --git a/CHANGELOG.md b/CHANGELOG.md index 9fd441fcb..b0028b710 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,11 +10,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * Added ignore_pagination and details arguments for get_report [#163](https://github.com/greenbone/python-gvm/pull/163) * Introduced Gmpv9 for [GMP 9](https://docs.greenbone.net/API/GMP/gmp-9.0.html) support [#157](https://github.com/greenbone/python-gvm/pull/157), - [#165](https://github.com/greenbone/python-gvm/pull/165) + [#165](https://github.com/greenbone/python-gvm/pull/165), + [#166](https://github.com/greenbone/python-gvm/pull/166) * Added new `create_audit` method, to create a task with the `usage_type` `audit` [#157](https://github.com/greenbone/python-gvm/pull/157) * Added new `create_policy` method, to create a config with the `usage_type` `policy` [#157](https://github.com/greenbone/python-gvm/pull/157) * Added the new methods `create_tls_certificate`, `modify_tls_certificate` and `clone_tls_certificate` to create, modify and copy TLS certificates [#157](https://github.com/greenbone/python-gvm/pull/157) * Added the new method `get_tls_certificates`, to request TLS certificates from the server [#157](https://github.com/greenbone/python-gvm/pull/157) +* Added the new method `get_tls_certificate`, to request a single TLS certificate + from the server [#166](https://github.com/greenbone/python-gvm/pull/166) ### Changed * Use Gmpv9 in gvm.protocols.latest module [#165](https://github.com/greenbone/python-gvm/pull/165) diff --git a/gvm/protocols/gmpv9/__init__.py b/gvm/protocols/gmpv9/__init__.py index 5158c161e..ec0eff65c 100644 --- a/gvm/protocols/gmpv9/__init__.py +++ b/gvm/protocols/gmpv9/__init__.py @@ -41,6 +41,8 @@ from .types import * from .types import _UsageType as UsageType +_EMPTY_POLICY_ID = '085569ce-73ed-11df-83c3-002264764cea' + PROTOCOL_VERSION = (9,) @@ -60,7 +62,7 @@ def get_protocol_version() -> tuple: def create_audit( self, name: str, - audit_id: str, + policy_id: str, target_id: str, scanner_id: str, *, @@ -77,7 +79,7 @@ def create_audit( Arguments: name: Name of the new audit - audit_id: UUID of scan config to use by the audit + policy_id: UUID of policy to use by the audit target_id: UUID of target to be scanned scanner_id: UUID of scanner to use for scanning the target comment: Comment for the audit @@ -97,10 +99,10 @@ def create_audit( return self.__create_task( name=name, - config_id=audit_id, + config_id=policy_id, target_id=target_id, scanner_id=scanner_id, - usage_type=UsageType.AUDIT, # pylint: disable=W0212 + usage_type=UsageType.AUDIT, function=self.create_audit.__name__, alterable=alterable, hosts_ordering=hosts_ordering, @@ -129,16 +131,19 @@ def create_config(self, config_id: str, name: str) -> Any: function=self.create_config.__name__, ) - def create_policy(self, policy_id: str, name: str) -> Any: + def create_policy(self, name: str, *, policy_id: str = None) -> Any: """Create a new policy config Arguments: - policy_id: UUID of the existing policy config - name: Name of the new scan config + name: Name of the new policy + policy_id: UUID of an existing policy as base. By default the empty + policy is used. Returns: The response. See :py:meth:`send_command` for details. """ + if policy_id is None: + policy_id = _EMPTY_POLICY_ID return self.__create_config( config_id=policy_id, name=name, @@ -211,11 +216,11 @@ def create_tls_certificate( """Create a new TLS certificate Arguments: - comment: Comment for the TLS certificate. name: Name of the TLS certificate, defaulting to the MD5 fingerprint. - trust: Whether the certificate is trusted. certificate: The Base64 encoded certificate data (x.509 DER or PEM). + comment: Comment for the TLS certificate. + trust: Whether the certificate is trusted. Returns: The response. See :py:meth:`send_command` for details. @@ -255,6 +260,8 @@ def get_tls_certificates( Arguments: filter: Filter term to use for the query filter_id: UUID of an existing filter to use for the query + include_certificate_data: Wether to include the certifacte data in + the response Returns: The response. See :py:meth:`send_command` for details. @@ -271,6 +278,27 @@ def get_tls_certificates( 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. + """ + if not tls_certificate_id: + raise RequiredArgument( + "get_tls_certificate requires tls_certificate_id argument" + ) + + cmd = XmlCommand("get_tls_certificates") + cmd.set_attribute("tls_certificate_id", tls_certificate_id) + + # for single tls certificate always request cert data + cmd.set_attribute("include_certificate_data", "1") + return self._send_xml_command(cmd) + def modify_tls_certificate( self, tls_certificate_id: str, diff --git a/tests/protocols/gmpv9/test_create_audit.py b/tests/protocols/gmpv9/test_create_audit.py index 9c7a66b4b..86019f555 100644 --- a/tests/protocols/gmpv9/test_create_audit.py +++ b/tests/protocols/gmpv9/test_create_audit.py @@ -31,7 +31,7 @@ class GmpCreateAuditCommandTestCase(Gmpv9TestCase): def test_create_task(self): self.gmp.create_audit( - name='foo', audit_id='c1', target_id='t1', scanner_id='s1' + name='foo', policy_id='c1', target_id='t1', scanner_id='s1' ) self.connection.send.has_been_called_with( @@ -47,51 +47,51 @@ def test_create_task(self): def test_create_audit_missing_name(self): with self.assertRaises(RequiredArgument): self.gmp.create_audit( - name=None, audit_id='c1', target_id='t1', scanner_id='s1' + name=None, policy_id='c1', target_id='t1', scanner_id='s1' ) with self.assertRaises(RequiredArgument): self.gmp.create_audit( - name='', audit_id='c1', target_id='t1', scanner_id='s1' + name='', policy_id='c1', target_id='t1', scanner_id='s1' ) - def test_create_audit_missing_audit_id(self): + def test_create_audit_missing_policy_id(self): with self.assertRaises(RequiredArgument): self.gmp.create_audit( - name='foo', audit_id=None, target_id='t1', scanner_id='s1' + name='foo', policy_id=None, target_id='t1', scanner_id='s1' ) with self.assertRaises(RequiredArgument): self.gmp.create_audit( - name='foo', audit_id='', target_id='t1', scanner_id='s1' + name='foo', policy_id='', target_id='t1', scanner_id='s1' ) def test_create_audit_missing_target_id(self): with self.assertRaises(RequiredArgument): self.gmp.create_audit( - name='foo', audit_id='c1', target_id=None, scanner_id='s1' + name='foo', policy_id='c1', target_id=None, scanner_id='s1' ) with self.assertRaises(RequiredArgument): self.gmp.create_audit( - name='foo', audit_id='c1', target_id='', scanner_id='s1' + name='foo', policy_id='c1', target_id='', scanner_id='s1' ) def test_create_audit_missing_scanner_id(self): with self.assertRaises(RequiredArgument): self.gmp.create_audit( - name='foo', audit_id='c1', target_id='t1', scanner_id=None + name='foo', policy_id='c1', target_id='t1', scanner_id=None ) with self.assertRaises(RequiredArgument): self.gmp.create_audit( - name='foo', audit_id='c1', target_id='t1', scanner_id='' + name='foo', policy_id='c1', target_id='t1', scanner_id='' ) def test_create_audit_with_comment(self): self.gmp.create_audit( name='foo', - audit_id='c1', + policy_id='c1', target_id='t1', scanner_id='s1', comment='bar', @@ -115,7 +115,7 @@ def test_create_audit_single_alert(self): self.gmp.create_audit( name='foo', - audit_id='c1', + policy_id='c1', target_id='t1', scanner_id='s1', alert_ids='a1', # will be removed in future @@ -137,7 +137,7 @@ def test_create_audit_single_alert(self): self.gmp.create_audit( name='foo', - audit_id='c1', + policy_id='c1', target_id='t1', scanner_id='s1', alert_ids=['a1'], @@ -157,7 +157,7 @@ def test_create_audit_single_alert(self): def test_create_audit_multiple_alerts(self): self.gmp.create_audit( name='foo', - audit_id='c1', + policy_id='c1', target_id='t1', scanner_id='s1', alert_ids=['a1', 'a2', 'a3'], @@ -179,7 +179,7 @@ def test_create_audit_multiple_alerts(self): def test_create_audit_with_alterable(self): self.gmp.create_audit( name='foo', - audit_id='c1', + policy_id='c1', target_id='t1', scanner_id='s1', alterable=True, @@ -198,7 +198,7 @@ def test_create_audit_with_alterable(self): self.gmp.create_audit( name='foo', - audit_id='c1', + policy_id='c1', target_id='t1', scanner_id='s1', alterable=False, @@ -218,7 +218,7 @@ def test_create_audit_with_alterable(self): def test_create_audit_with_hosts_ordering(self): self.gmp.create_audit( name='foo', - audit_id='c1', + policy_id='c1', target_id='t1', scanner_id='s1', hosts_ordering=HostsOrdering.REVERSE, @@ -239,7 +239,7 @@ def test_create_audit_invalid_hosts_ordering(self): with self.assertRaises(InvalidArgument): self.gmp.create_audit( name='foo', - audit_id='c1', + policy_id='c1', target_id='t1', scanner_id='s1', hosts_ordering='foo', @@ -248,7 +248,7 @@ def test_create_audit_invalid_hosts_ordering(self): def test_create_audit_with_schedule(self): self.gmp.create_audit( name='foo', - audit_id='c1', + policy_id='c1', target_id='t1', scanner_id='s1', schedule_id='s1', @@ -268,7 +268,7 @@ def test_create_audit_with_schedule(self): def test_create_audit_with_schedule_and_schedule_periods(self): self.gmp.create_audit( name='foo', - audit_id='c1', + policy_id='c1', target_id='t1', scanner_id='s1', schedule_id='s1', @@ -289,7 +289,7 @@ def test_create_audit_with_schedule_and_schedule_periods(self): self.gmp.create_audit( name='foo', - audit_id='c1', + policy_id='c1', target_id='t1', scanner_id='s1', schedule_id='s1', @@ -312,7 +312,7 @@ def test_create_audit_with_schedule_and_invalid_schedule_periods(self): with self.assertRaises(InvalidArgument): self.gmp.create_audit( name='foo', - audit_id='c1', + policy_id='c1', target_id='t1', scanner_id='s1', schedule_id='s1', @@ -322,7 +322,7 @@ def test_create_audit_with_schedule_and_invalid_schedule_periods(self): with self.assertRaises(InvalidArgument): self.gmp.create_audit( name='foo', - audit_id='c1', + policy_id='c1', target_id='t1', scanner_id='s1', schedule_id='s1', @@ -332,7 +332,7 @@ def test_create_audit_with_schedule_and_invalid_schedule_periods(self): def test_create_audit_with_observers(self): self.gmp.create_audit( name='foo', - audit_id='c1', + policy_id='c1', target_id='t1', scanner_id='s1', observers=['u1', 'u2'], @@ -353,7 +353,7 @@ def test_create_audit_invalid_observers(self): with self.assertRaises(InvalidArgument): self.gmp.create_audit( name='foo', - audit_id='c1', + policy_id='c1', target_id='t1', scanner_id='s1', observers='', @@ -362,7 +362,7 @@ def test_create_audit_invalid_observers(self): with self.assertRaises(InvalidArgument): self.gmp.create_audit( name='foo', - audit_id='c1', + policy_id='c1', target_id='t1', scanner_id='s1', observers='foo', @@ -371,7 +371,7 @@ def test_create_audit_invalid_observers(self): def test_create_audit_with_preferences(self): self.gmp.create_audit( name='foo', - audit_id='c1', + policy_id='c1', target_id='t1', scanner_id='s1', preferences=OrderedDict([('foo', 'bar'), ('lorem', 'ipsum')]), @@ -401,7 +401,7 @@ def test_create_audit_invalid_preferences(self): with self.assertRaises(InvalidArgument): self.gmp.create_audit( name='foo', - audit_id='c1', + policy_id='c1', target_id='t1', scanner_id='s1', preferences='', @@ -410,7 +410,7 @@ def test_create_audit_invalid_preferences(self): with self.assertRaises(InvalidArgument): self.gmp.create_audit( name='foo', - audit_id='c1', + policy_id='c1', target_id='t1', scanner_id='s1', preferences=['foo', 'bar'], @@ -420,7 +420,7 @@ def test_create_audit_don_t_allow_container_task(self): with self.assertRaises(InvalidArgument): self.gmp.create_audit( name='foo', - audit_id='c1', + policy_id='c1', target_id='0', scanner_id='s1', observers='', @@ -430,7 +430,7 @@ def test_create_audit_don_t_allow_container_task(self): with self.assertRaises(RequiredArgument): self.gmp.create_audit( name='foo', - audit_id='c1', + policy_id='c1', target_id=0, scanner_id='s1', observers='', diff --git a/tests/protocols/gmpv9/test_create_policy.py b/tests/protocols/gmpv9/test_create_policy.py index 72c09388e..2cb7f53b8 100644 --- a/tests/protocols/gmpv9/test_create_policy.py +++ b/tests/protocols/gmpv9/test_create_policy.py @@ -25,22 +25,26 @@ class GmpCreatePolicyTestCase(Gmpv9TestCase): def test_create_policy(self): - self.gmp.create_policy('a1', 'foo') + self.gmp.create_policy('foo') self.connection.send.has_been_called_with( '' - 'a1' + '085569ce-73ed-11df-83c3-002264764cea' 'foo' 'policy' '' ) - def test_missing_policy_id(self): - with self.assertRaises(RequiredArgument): - self.gmp.create_policy(policy_id='', name='foo') + def test_create_with_policy_id(self): + self.gmp.create_policy('foo', policy_id='p1') - with self.assertRaises(RequiredArgument): - self.gmp.create_policy(policy_id=None, name='foo') + self.connection.send.has_been_called_with( + '' + 'p1' + 'foo' + 'policy' + '' + ) def test_missing_name(self): with self.assertRaises(RequiredArgument): diff --git a/tests/protocols/gmpv9/test_get_tls_certificate.py b/tests/protocols/gmpv9/test_get_tls_certificate.py new file mode 100644 index 000000000..a933230ad --- /dev/null +++ b/tests/protocols/gmpv9/test_get_tls_certificate.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2019 Greenbone Networks GmbH +# +# SPDX-License-Identifier: GPL-3.0-or-later +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +import unittest + +from gvm.errors import GvmError + +from . import Gmpv9TestCase + + +class GmpGetTlsCertificateTestCase(Gmpv9TestCase): + def test_get_tls_certificate(self): + self.gmp.get_tls_certificate('t1') + + self.connection.send.has_been_called_with( + '' + ) + + def test_fail_without_tls_certificate_id(self): + with self.assertRaises(GvmError): + self.gmp.get_tls_certificate(None) + + with self.assertRaises(GvmError): + self.gmp.get_tls_certificate('') + + +if __name__ == '__main__': + unittest.main()