Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add: Kerberos credential for targets #2332

Merged
merged 5 commits into from
Dec 6, 2024
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
135 changes: 134 additions & 1 deletion src/gmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -950,6 +950,7 @@ typedef struct
char *esxi_credential_id; ///< ESXi credential for new target.
char *esxi_lsc_credential_id; ///< ESXi credential (deprecated).
char *snmp_credential_id; ///< SNMP credential for new target.
char *krb5_credential_id; ///< Kerberos 5 credential for new target.
char *name; ///< Name of new target.
} create_target_data_t;

Expand Down Expand Up @@ -982,6 +983,7 @@ create_target_data_reset (create_target_data_t *data)
free (data->esxi_credential_id);
free (data->esxi_lsc_credential_id);
free (data->snmp_credential_id);
free (data->krb5_credential_id);
free (data->name);

memset (data, 0, sizeof (create_target_data_t));
Expand Down Expand Up @@ -2880,6 +2882,7 @@ typedef struct
char *esxi_credential_id; ///< ESXi credential for target.
char *esxi_lsc_credential_id; ///< ESXi credential for target (deprecated).
char *snmp_credential_id; ///< SNMP credential for target.
char *krb5_credential_id; ///< Kerberos 5 credential for target.
char *target_id; ///< Target UUID.
} modify_target_data_t;

Expand Down Expand Up @@ -2910,6 +2913,7 @@ modify_target_data_reset (modify_target_data_t *data)
free (data->esxi_credential_id);
free (data->esxi_lsc_credential_id);
free (data->snmp_credential_id);
free (data->krb5_credential_id);
free (data->target_id);

memset (data, 0, sizeof (modify_target_data_t));
Expand Down Expand Up @@ -4292,6 +4296,7 @@ typedef enum
CLIENT_CREATE_TARGET_NAME,
CLIENT_CREATE_TARGET_PORT_LIST,
CLIENT_CREATE_TARGET_PORT_RANGE,
CLIENT_CREATE_TARGET_KRB5_CREDENTIAL,
CLIENT_CREATE_TARGET_SMB_CREDENTIAL,
CLIENT_CREATE_TARGET_SNMP_CREDENTIAL,
CLIENT_CREATE_TARGET_SSH_CREDENTIAL,
Expand Down Expand Up @@ -4529,6 +4534,7 @@ typedef enum
CLIENT_MODIFY_TARGET_REVERSE_LOOKUP_UNIFY,
CLIENT_MODIFY_TARGET_NAME,
CLIENT_MODIFY_TARGET_PORT_LIST,
CLIENT_MODIFY_TARGET_KRB5_CREDENTIAL,
CLIENT_MODIFY_TARGET_SMB_CREDENTIAL,
CLIENT_MODIFY_TARGET_SNMP_CREDENTIAL,
CLIENT_MODIFY_TARGET_SSH_CREDENTIAL,
Expand Down Expand Up @@ -6631,6 +6637,12 @@ gmp_xml_handle_start_element (/* unused */ GMarkupParseContext* context,
&modify_target_data->port_list_id);
set_client_state (CLIENT_MODIFY_TARGET_PORT_LIST);
}
else if (strcasecmp ("KRB5_CREDENTIAL", element_name) == 0)
{
append_attribute (attribute_names, attribute_values, "id",
&modify_target_data->krb5_credential_id);
set_client_state (CLIENT_MODIFY_TARGET_KRB5_CREDENTIAL);
}
else if (strcasecmp ("SSH_CREDENTIAL", element_name) == 0)
{
append_attribute (attribute_names, attribute_values, "id",
Expand Down Expand Up @@ -7642,6 +7654,12 @@ gmp_xml_handle_start_element (/* unused */ GMarkupParseContext* context,
gvm_append_string (&create_target_data->port_range, "");
set_client_state (CLIENT_CREATE_TARGET_PORT_RANGE);
}
else if (strcasecmp ("KRB5_CREDENTIAL", element_name) == 0)
{
append_attribute (attribute_names, attribute_values, "id",
&create_target_data->krb5_credential_id);
set_client_state (CLIENT_CREATE_TARGET_KRB5_CREDENTIAL);
}
else if (strcasecmp ("SSH_CREDENTIAL", element_name) == 0)
{
append_attribute (attribute_names, attribute_values, "id",
Expand Down Expand Up @@ -17857,18 +17875,20 @@ handle_get_targets (gmp_parser_t *gmp_parser, GError **error)
char *ssh_name, *ssh_uuid, *smb_name, *smb_uuid;
char *esxi_name, *esxi_uuid, *snmp_name, *snmp_uuid;
char *ssh_elevate_name, *ssh_elevate_uuid;
char *krb5_name, *krb5_uuid;
const char *port_list_uuid, *port_list_name, *ssh_port;
const char *hosts, *exclude_hosts, *reverse_lookup_only;
const char *reverse_lookup_unify, *allow_simultaneous_ips;
credential_t ssh_credential, smb_credential;
credential_t esxi_credential, snmp_credential;
credential_t ssh_elevate_credential;
credential_t ssh_elevate_credential, krb5_credential;
int port_list_trash, max_hosts, port_list_available;
int ssh_credential_available;
int smb_credential_available;
int esxi_credential_available;
int snmp_credential_available;
int ssh_elevate_credential_available;
int krb5_credential_available;

ret = get_next (&targets, &get_targets_data->get, &first,
&count, init_target_iterator);
Expand All @@ -17886,6 +17906,7 @@ handle_get_targets (gmp_parser_t *gmp_parser, GError **error)
snmp_credential = target_iterator_snmp_credential (&targets);
ssh_elevate_credential
= target_iterator_ssh_elevate_credential (&targets);
krb5_credential = target_iterator_krb5_credential (&targets);

ssh_credential_available = 1;
if (ssh_credential)
Expand Down Expand Up @@ -18043,6 +18064,38 @@ handle_get_targets (gmp_parser_t *gmp_parser, GError **error)
ssh_elevate_uuid = NULL;
}

krb5_credential_available = 1;
if (krb5_credential)
{
if (get_targets_data->get.trash
&& target_iterator_krb5_trash (&targets))
{
krb5_name
= trash_credential_name (krb5_credential);
krb5_uuid
= trash_credential_uuid (krb5_credential);
krb5_credential_available
= trash_credential_readable (krb5_credential);
}
else
{
credential_t found;

krb5_name = credential_name (krb5_credential);
krb5_uuid = credential_uuid (krb5_credential);
if (find_credential_with_permission (krb5_uuid,
&found,
"get_credentials"))
abort ();
krb5_credential_available = (found > 0);
}
}
else
{
krb5_name = NULL;
krb5_uuid = NULL;
}

port_list_uuid = target_iterator_port_list_uuid (&targets);
port_list_name = target_iterator_port_list_name (&targets);
port_list_trash = target_iterator_port_list_trash (&targets);
Expand Down Expand Up @@ -18153,6 +18206,18 @@ handle_get_targets (gmp_parser_t *gmp_parser, GError **error)
SEND_TO_CLIENT_OR_FAIL ("<permissions/>");

SENDF_TO_CLIENT_OR_FAIL ("</ssh_elevate_credential>"
"<krb5_credential id=\"%s\">"
"<name>%s</name>"
"<trash>%i</trash>",
krb5_uuid ? krb5_uuid : "",
krb5_name ? krb5_name : "",
(get_targets_data->get.trash
&& target_iterator_krb5_trash (&targets)));

if (krb5_credential_available == 0)
SEND_TO_CLIENT_OR_FAIL ("<permissions/>");

SENDF_TO_CLIENT_OR_FAIL ("</krb5_credential>"
"<reverse_lookup_only>"
"%s"
"</reverse_lookup_only>"
Expand Down Expand Up @@ -18210,6 +18275,8 @@ handle_get_targets (gmp_parser_t *gmp_parser, GError **error)
free (esxi_uuid);
free (ssh_elevate_name);
free (ssh_elevate_uuid);
free (krb5_name);
free (krb5_uuid);
}
cleanup_iterator (&targets);
filtered = get_targets_data->get.id
Expand Down Expand Up @@ -22958,6 +23025,7 @@ gmp_xml_handle_end_element (/* unused */ GMarkupParseContext* context,
credential_t ssh_credential = 0, ssh_elevate_credential = 0;
credential_t smb_credential = 0;
credential_t esxi_credential = 0, snmp_credential = 0;
credential_t krb5_credential = 0;
target_t new_target;

if (create_target_data->copy)
Expand Down Expand Up @@ -23026,6 +23094,12 @@ gmp_xml_handle_end_element (/* unused */ GMarkupParseContext* context,
(XML_ERROR_SYNTAX ("create_target",
"Hosts must be at least one"
" character long"));
else if (create_target_data->smb_credential_id
&& create_target_data->krb5_credential_id)
SEND_TO_CLIENT_OR_FAIL
(XML_ERROR_SYNTAX ("create_target",
"Targets cannot have both an SMB and"
" Kerberos 5 credential"));
else if (create_target_data->ssh_credential_id
&& find_credential_with_permission
(create_target_data->ssh_credential_id,
Expand Down Expand Up @@ -23134,6 +23208,25 @@ gmp_xml_handle_end_element (/* unused */ GMarkupParseContext* context,
return;
}
}
else if (create_target_data->krb5_credential_id
&& find_credential_with_permission
(create_target_data->krb5_credential_id,
&krb5_credential,
"get_credentials"))
SEND_TO_CLIENT_OR_FAIL (XML_INTERNAL_ERROR ("create_target"));
timopollmeier marked this conversation as resolved.
Show resolved Hide resolved
else if (create_target_data->krb5_credential_id
&& krb5_credential == 0)
{
if (send_find_error_to_client
("create_target", "Credential",
create_target_data->krb5_credential_id,
gmp_parser))
timopollmeier marked this conversation as resolved.
Show resolved Hide resolved
{
error_send_to_client (error);
return;
}
}

/* Create target from host string. */
else switch (create_target
(create_target_data->name,
Expand All @@ -23151,6 +23244,7 @@ gmp_xml_handle_end_element (/* unused */ GMarkupParseContext* context,
smb_credential,
esxi_credential,
snmp_credential,
krb5_credential,
create_target_data->reverse_lookup_only,
create_target_data->reverse_lookup_unify,
create_target_data->alive_tests,
Expand Down Expand Up @@ -23260,6 +23354,13 @@ gmp_xml_handle_end_element (/* unused */ GMarkupParseContext* context,
" different from the SSH credential"));
log_event_fail ("target", "Target", NULL, "created");
break;
case 16:
SEND_TO_CLIENT_OR_FAIL
(XML_ERROR_SYNTAX ("create_target",
"Kerberos 5 credential must be of type"
" 'krb5'"));
log_event_fail ("target", "Target", NULL, "created");
break;
case 99:
SEND_TO_CLIENT_OR_FAIL
(XML_ERROR_SYNTAX ("create_target",
Expand Down Expand Up @@ -23299,6 +23400,7 @@ gmp_xml_handle_end_element (/* unused */ GMarkupParseContext* context,
CLOSE (CLIENT_CREATE_TARGET, NAME);
CLOSE (CLIENT_CREATE_TARGET, PORT_LIST);
CLOSE (CLIENT_CREATE_TARGET, PORT_RANGE);
CLOSE (CLIENT_CREATE_TARGET, KRB5_CREDENTIAL);
CLOSE (CLIENT_CREATE_TARGET, SSH_CREDENTIAL);
CLOSE (CLIENT_CREATE_TARGET, SSH_LSC_CREDENTIAL);
CLOSE (CLIENT_CREATE_TARGET, SSH_ELEVATE_CREDENTIAL);
Expand Down Expand Up @@ -25758,6 +25860,7 @@ gmp_xml_handle_end_element (/* unused */ GMarkupParseContext* context,
? modify_target_data->esxi_credential_id
: modify_target_data->esxi_lsc_credential_id,
modify_target_data->snmp_credential_id,
modify_target_data->krb5_credential_id,
modify_target_data->reverse_lookup_only,
modify_target_data->reverse_lookup_unify,
modify_target_data->alive_tests,
Expand Down Expand Up @@ -26007,6 +26110,35 @@ gmp_xml_handle_end_element (/* unused */ GMarkupParseContext* context,
log_event_fail ("target", "Target",
modify_target_data->target_id, "modified");
break;
case 26:
log_event_fail ("target", "Target",
modify_target_data->target_id,
"modified");
if (send_find_error_to_client
("modify_target", "Credential",
modify_target_data->krb5_credential_id,
gmp_parser))
{
error_send_to_client (error);
return;
}
break;
case 27:
SEND_TO_CLIENT_OR_FAIL
(XML_ERROR_SYNTAX ("modify_target",
"Kerberos 5 credential must be of type"
" 'krb5'"));
log_event_fail ("target", "Target",
modify_target_data->target_id, "modified");
break;
case 28:
SEND_TO_CLIENT_OR_FAIL
(XML_ERROR_SYNTAX ("modify_target",
"Targets cannot have both an SMB and"
" Kerberos 5 credential"));
log_event_fail ("target", "Target",
modify_target_data->target_id, "modified");
break;
case 99:
SEND_TO_CLIENT_OR_FAIL
(XML_ERROR_SYNTAX ("modify_target",
Expand Down Expand Up @@ -26046,6 +26178,7 @@ gmp_xml_handle_end_element (/* unused */ GMarkupParseContext* context,
CLOSE (CLIENT_MODIFY_TARGET, HOSTS);
CLOSE (CLIENT_MODIFY_TARGET, NAME);
CLOSE (CLIENT_MODIFY_TARGET, PORT_LIST);
CLOSE (CLIENT_MODIFY_TARGET, KRB5_CREDENTIAL);
CLOSE (CLIENT_MODIFY_TARGET, SSH_CREDENTIAL);
CLOSE (CLIENT_MODIFY_TARGET, SSH_LSC_CREDENTIAL);
CLOSE (CLIENT_MODIFY_TARGET, SSH_ELEVATE_CREDENTIAL);
Expand Down
61 changes: 60 additions & 1 deletion src/manage.c
Original file line number Diff line number Diff line change
Expand Up @@ -2396,6 +2396,61 @@ target_osp_snmp_credential (target_t target)
return NULL;
}

/**
* @brief Get the Kerberos 5 credential of a target as an osp_credential_t
*
* @param[in] target The target to get the credential from.
*
* @return Pointer to a newly allocated osp_credential_t
*/
static osp_credential_t *
target_osp_krb5_credential (target_t target)
{
credential_t credential;
credential = target_credential (target, "krb5");
if (credential)
{
iterator_t iter;
osp_credential_t *osp_credential;

init_credential_iterator_one (&iter, credential);
if (!next (&iter))
{
g_warning ("%s: Kerberos 5 Credential not found.", __func__);
cleanup_iterator (&iter);
return NULL;
}
if (strcmp (credential_iterator_type (&iter), "krb5"))
{
g_warning ("%s: Kerberos 5 Credential not of type 'krb5'.",
__func__);
cleanup_iterator (&iter);
return NULL;
}

osp_credential = osp_credential_new ("up", "krb5", NULL);
osp_credential_set_auth_data (osp_credential,
"username",
credential_iterator_login (&iter)
?: "");
osp_credential_set_auth_data (osp_credential,
"password",
credential_iterator_password (&iter)
?: "");
osp_credential_set_auth_data (osp_credential,
"kdc",
credential_iterator_kdc (&iter)
?: "");
osp_credential_set_auth_data (osp_credential,
"realm",
credential_iterator_realm (&iter)
?: "");
cleanup_iterator (&iter);
return osp_credential;
}
return NULL;
}

/**
* @brief Prepare a report for resuming an OSP scan
*
Expand Down Expand Up @@ -2571,7 +2626,7 @@ launch_osp_openvas_task (task_t task, target_t target, const char *scan_id,
GSList *osp_targets, *vts;
GHashTable *vts_hash_table;
osp_credential_t *ssh_credential, *smb_credential, *esxi_credential;
osp_credential_t *snmp_credential;
osp_credential_t *snmp_credential, *krb5_credential;
gchar *max_checks, *max_hosts, *hosts_ordering;
GHashTable *scanner_options;
int ret, empty;
Expand Down Expand Up @@ -2663,6 +2718,10 @@ launch_osp_openvas_task (task_t task, target_t target, const char *scan_id,
if (snmp_credential)
osp_target_add_credential (osp_target, snmp_credential);

krb5_credential = target_osp_krb5_credential (target);
if (krb5_credential)
osp_target_add_credential (osp_target, krb5_credential);

/* Initialize vts table for vulnerability tests and their preferences */
vts = NULL;
vts_hash_table
Expand Down
Loading
Loading