Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 90 additions & 0 deletions gvm/protocols/gmp/_gmpnext.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,96 @@ def get_agent_support_bundle(
)
)

def create_active_directory_credential(
self,
name: str,
*,
host: str,
bind_dn: str,
base_dn: str,
bind_password: str,
tls_mode: str,
comment: str | None = None,
port: int | None = None,
ca_certificate: str | None = None,
) -> T:
"""Create an Active Directory credential.

Requires AD integration to be enabled in gvmd.

Args:
name: Name of the credential.
host: Active Directory server hostname or IP address.
bind_dn: Distinguished name used to bind to the directory.
base_dn: Base distinguished name for directory searches.
bind_password: Password used to bind to the directory.
tls_mode: TLS mode, either "ldaps" or "starttls".
comment: Optional comment for the credential.
port: Server port (1 to 65535). Omit to use the connector default.
ca_certificate: Optional CA certificate in PEM format.
"""
return self._send_request_and_transform_response(
Credentials.create_active_directory_credential(
name=name,
host=host,
bind_dn=bind_dn,
base_dn=base_dn,
bind_password=bind_password,
tls_mode=tls_mode,
comment=comment,
port=port,
ca_certificate=ca_certificate,
)
)

def modify_active_directory_credential(
self,
credential_id: EntityID,
*,
name: str | None = None,
comment: str | None = None,
host: str | None = None,
bind_dn: str | None = None,
base_dn: str | None = None,
bind_password: str | None = None,
tls_mode: str | None = None,
port: int | str | None = None,
ca_certificate: str | None = None,
) -> T:
"""Modify an Active Directory credential.

Requires AD integration to be enabled in gvmd. Fields set to None
are left unchanged.

Args:
credential_id: UUID of the credential to modify.
name: New name of the credential.
comment: New comment. An empty string clears the comment.
host: Active Directory server hostname or IP address.
bind_dn: Distinguished name used to bind to the directory.
base_dn: Base distinguished name for directory searches.
bind_password: Password used to bind to the directory.
tls_mode: TLS mode, either "ldaps" or "starttls".
port: Server port (1 to 65535), or an empty string to restore
the connector default. Nonempty strings are not accepted.
ca_certificate: CA certificate in PEM format. An empty string
clears the certificate.
"""
return self._send_request_and_transform_response(
Credentials.modify_active_directory_credential(
credential_id=credential_id,
name=name,
comment=comment,
host=host,
bind_dn=bind_dn,
base_dn=base_dn,
bind_password=bind_password,
tls_mode=tls_mode,
port=port,
ca_certificate=ca_certificate,
)
)

def create_credential_store_credential(
self,
name: str,
Expand Down
2 changes: 1 addition & 1 deletion gvm/protocols/gmp/requests/next/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from gvm.protocols.gmp.requests.next._credentials import (
Credentials,
CredentialStoreCredentialType,
CredentialType,
)
from gvm.protocols.gmp.requests.next._features import (
Features,
Expand Down Expand Up @@ -76,7 +77,6 @@
CertBundAdvisories,
Cpes,
CredentialFormat,
CredentialType,
Cves,
DfnCertAdvisories,
EntityType,
Expand Down
222 changes: 222 additions & 0 deletions gvm/protocols/gmp/requests/next/_credentials.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,229 @@ class CredentialStoreCredentialType(Enum):
PASSWORD_ONLY = "cs_pw"


class CredentialType(Enum):
"""Enum for credential types"""

CLIENT_CERTIFICATE = "cc"
SNMP = "snmp"
USERNAME_PASSWORD = "up"
USERNAME_SSH_KEY = "usk"
SMIME_CERTIFICATE = "smime"
PGP_ENCRYPTION_KEY = "pgp"
PASSWORD_ONLY = "pw"
ACTIVE_DIRECTORY = "ad"


class Credentials(CredentialsV224):
@classmethod
def create_active_directory_credential(
Comment thread
ozgen marked this conversation as resolved.
cls,
name: str,
*,
host: str,
bind_dn: str,
base_dn: str,
bind_password: str,
tls_mode: str,
comment: str | None = None,
port: int | None = None,
ca_certificate: str | None = None,
) -> Request:
"""Create an Active Directory credential.

Requires AD integration to be enabled in gvmd.

Args:
name: Name of the credential.
host: Active Directory server hostname or IP address.
bind_dn: Distinguished name used to bind to the directory.
base_dn: Base distinguished name for directory searches.
bind_password: Password used to bind to the directory.
tls_mode: TLS mode, either "ldaps" or "starttls".
comment: Optional comment for the credential.
port: Server port (1 to 65535). Omit to use the connector default.
ca_certificate: Optional CA certificate in PEM format.
"""
if not name:
raise RequiredArgument(
function=cls.create_active_directory_credential.__name__,
argument="name",
)

if not host:
raise RequiredArgument(
function=cls.create_active_directory_credential.__name__,
argument="host",
)

if not bind_dn:
raise RequiredArgument(
function=cls.create_active_directory_credential.__name__,
argument="bind_dn",
)

if not base_dn:
raise RequiredArgument(
function=cls.create_active_directory_credential.__name__,
argument="base_dn",
)

if not bind_password:
raise RequiredArgument(
function=cls.create_active_directory_credential.__name__,
argument="bind_password",
)

if not tls_mode:
raise RequiredArgument(
function=cls.create_active_directory_credential.__name__,
argument="tls_mode",
)

if tls_mode not in ("ldaps", "starttls"):
raise InvalidArgument(
function=cls.create_active_directory_credential.__name__,
argument="tls_mode",
)

if port is not None and (
not isinstance(port, int) or not 1 <= port <= 65535
):
raise InvalidArgument(
function=cls.create_active_directory_credential.__name__,
argument="port",
)

cmd = XmlCommand("create_credential")
cmd.add_element("name", name)
cmd.add_element("type", CredentialType.ACTIVE_DIRECTORY.value)
if comment is not None:
cmd.add_element("comment", comment)
cmd.add_element("host", host)
cmd.add_element("bind_dn", bind_dn)
cmd.add_element("base_dn", base_dn)
cmd.add_element("bind_password", bind_password)
cmd.add_element("tls_mode", tls_mode)
if port is not None:
cmd.add_element("port", str(port))
if ca_certificate is not None:
cmd.add_element("ca_certificate", ca_certificate)
return cmd

@classmethod
def modify_active_directory_credential(
cls,
credential_id: EntityID,
*,
name: str | None = None,
comment: str | None = None,
host: str | None = None,
bind_dn: str | None = None,
base_dn: str | None = None,
bind_password: str | None = None,
tls_mode: str | None = None,
port: int | str | None = None,
Comment thread
ozgen marked this conversation as resolved.
ca_certificate: str | None = None,
) -> Request:
"""Modify an Active Directory credential.

Requires AD integration to be enabled in gvmd. Fields set to None
are left unchanged.

Args:
credential_id: UUID of the credential to modify.
name: New name of the credential.
comment: New comment. An empty string clears the comment.
host: Active Directory server hostname or IP address.
bind_dn: Distinguished name used to bind to the directory.
base_dn: Base distinguished name for directory searches.
bind_password: Password used to bind to the directory.
tls_mode: TLS mode, either "ldaps" or "starttls".
port: Server port (1 to 65535), or an empty string to restore
the connector default. Nonempty strings are not accepted.
ca_certificate: CA certificate in PEM format. An empty string
clears the certificate.
"""
if not credential_id:
raise RequiredArgument(
function=cls.modify_active_directory_credential.__name__,
argument="credential_id",
)

if name is not None and not name:
raise RequiredArgument(
function=cls.modify_active_directory_credential.__name__,
argument="name",
)

if host is not None and not host:
raise RequiredArgument(
function=cls.modify_active_directory_credential.__name__,
argument="host",
)

if bind_dn is not None and not bind_dn:
raise RequiredArgument(
function=cls.modify_active_directory_credential.__name__,
argument="bind_dn",
)

if base_dn is not None and not base_dn:
raise RequiredArgument(
function=cls.modify_active_directory_credential.__name__,
argument="base_dn",
)

if bind_password is not None and not bind_password:
raise RequiredArgument(
function=cls.modify_active_directory_credential.__name__,
argument="bind_password",
)

if tls_mode is not None and not tls_mode:
raise RequiredArgument(
function=cls.modify_active_directory_credential.__name__,
argument="tls_mode",
)

if tls_mode is not None and tls_mode not in ("ldaps", "starttls"):
raise InvalidArgument(
function=cls.modify_active_directory_credential.__name__,
argument="tls_mode",
)

if (
port is not None
and port != ""
and (not isinstance(port, int) or not 1 <= port <= 65535)
):
raise InvalidArgument(
function=cls.modify_active_directory_credential.__name__,
argument="port",
)

cmd = XmlCommand("modify_credential")
cmd.set_attribute("credential_id", str(credential_id))
if name is not None:
cmd.add_element("name", str(name))
if comment is not None:
cmd.add_element("comment", str(comment))
if host is not None:
cmd.add_element("host", str(host))
if bind_dn is not None:
cmd.add_element("bind_dn", str(bind_dn))
if base_dn is not None:
cmd.add_element("base_dn", str(base_dn))
if bind_password is not None:
cmd.add_element("bind_password", str(bind_password))
if tls_mode is not None:
cmd.add_element("tls_mode", str(tls_mode))
if port is not None:
cmd.add_element("port", str(port))
if ca_certificate is not None:
cmd.add_element("ca_certificate", str(ca_certificate))
return cmd

@classmethod
def create_credential_store_credential(
cls,
Expand Down
8 changes: 8 additions & 0 deletions tests/protocols/gmpnext/entities/credentials/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,22 @@
#
# SPDX-License-Identifier: GPL-3.0-or-later

from .test_create_active_directory_credential import (
GmpCreateActiveDirectoryCredentialTestMixin,
)
from .test_create_credential_store_credential import (
GmpCreateCredentialStoreCredentialTestMixin,
)
from .test_modify_active_directory_credential import (
GmpModifyActiveDirectoryCredentialTestMixin,
)
from .test_modify_credential_store_credential import (
GmpModifyCredentialStoreCredentialTestMixin,
)

__all__ = (
"GmpCreateActiveDirectoryCredentialTestMixin",
"GmpCreateCredentialStoreCredentialTestMixin",
"GmpModifyActiveDirectoryCredentialTestMixin",
"GmpModifyCredentialStoreCredentialTestMixin",
)
Loading
Loading