diff --git a/src/gmp.c b/src/gmp.c index 492c39920..ad20b20ba 100644 --- a/src/gmp.c +++ b/src/gmp.c @@ -12203,8 +12203,9 @@ handle_get_credentials (gmp_parser_t *gmp_parser, GError **error) INIT_GET (credential, Credential); - ret = init_credential_iterator (&credentials, - &get_credentials_data->get); + ret = init_credential_iterator_format (&credentials, + &get_credentials_data->get, + format); if (ret) { switch (ret) @@ -12242,7 +12243,7 @@ handle_get_credentials (gmp_parser_t *gmp_parser, GError **error) SEND_GET_START("credential"); while (1) { - const char *private_key, *public_key, *login, *type, *cert; + const char *login, *type, *cert; gchar *formats_xml; ret = get_next (&credentials, &get_credentials_data->get, @@ -12256,8 +12257,6 @@ handle_get_credentials (gmp_parser_t *gmp_parser, GError **error) } SEND_GET_COMMON (credential, &get_credentials_data->get, &credentials); - private_key = credential_iterator_private_key (&credentials); - public_key = credential_iterator_public_key (&credentials); login = credential_iterator_login (&credentials); type = credential_iterator_type (&credentials); cert = credential_iterator_certificate (&credentials); @@ -12336,6 +12335,10 @@ handle_get_credentials (gmp_parser_t *gmp_parser, GError **error) case CREDENTIAL_FORMAT_KEY: { + const char *public_key; + + public_key = credential_iterator_public_key (&credentials); + if (public_key && strcmp (public_key, "")) { SENDF_TO_CLIENT_OR_FAIL @@ -12344,8 +12347,9 @@ handle_get_credentials (gmp_parser_t *gmp_parser, GError **error) else { char *pub; - const char *pass; + const char *pass, *private_key; + private_key = credential_iterator_private_key (&credentials); pass = credential_iterator_password (&credentials); pub = gvm_ssh_public_from_private (private_key, pass); SENDF_TO_CLIENT_OR_FAIL @@ -17341,147 +17345,163 @@ 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); + ssh_credential_available = 1; - if (get_targets_data->get.trash - && target_iterator_ssh_trash (&targets)) + if (ssh_credential) { - ssh_name = trash_credential_name (ssh_credential); - ssh_uuid = trash_credential_uuid (ssh_credential); - ssh_credential_available - = trash_credential_readable (ssh_credential); - } - else if (ssh_credential) - { - credential_t found; - - ssh_name = credential_name (ssh_credential); - ssh_uuid = credential_uuid (ssh_credential); - if (find_credential_with_permission - (ssh_uuid, - &found, - "get_credentials")) - abort (); - ssh_credential_available = (found > 0); + if (get_targets_data->get.trash + && target_iterator_ssh_trash (&targets)) + { + ssh_name = trash_credential_name (ssh_credential); + ssh_uuid = trash_credential_uuid (ssh_credential); + ssh_credential_available + = trash_credential_readable (ssh_credential); + } + else + { + credential_t found; + + ssh_name = credential_name (ssh_credential); + ssh_uuid = credential_uuid (ssh_credential); + if (find_credential_with_permission (ssh_uuid, + &found, + "get_credentials")) + abort (); + ssh_credential_available = (found > 0); + } } else { ssh_name = NULL; ssh_uuid = NULL; } + smb_credential_available = 1; - if (get_targets_data->get.trash - && target_iterator_smb_trash (&targets)) + if (smb_credential) { - smb_name = trash_credential_name (smb_credential); - smb_uuid = trash_credential_uuid (smb_credential); - smb_credential_available - = trash_credential_readable (smb_credential); - } - else if (smb_credential) - { - credential_t found; - - smb_name = credential_name (smb_credential); - smb_uuid = credential_uuid (smb_credential); - if (find_credential_with_permission - (smb_uuid, - &found, - "get_credentials")) - abort (); - smb_credential_available = (found > 0); + if (get_targets_data->get.trash + && target_iterator_smb_trash (&targets)) + { + smb_name = trash_credential_name (smb_credential); + smb_uuid = trash_credential_uuid (smb_credential); + smb_credential_available + = trash_credential_readable (smb_credential); + } + else + { + credential_t found; + + smb_name = credential_name (smb_credential); + smb_uuid = credential_uuid (smb_credential); + if (find_credential_with_permission (smb_uuid, + &found, + "get_credentials")) + abort (); + smb_credential_available = (found > 0); + } } else { smb_name = NULL; smb_uuid = NULL; } + esxi_credential_available = 1; - if (get_targets_data->get.trash - && target_iterator_esxi_trash (&targets)) + if (esxi_credential) { - esxi_name - = trash_credential_name (esxi_credential); - esxi_uuid - = trash_credential_uuid (esxi_credential); - esxi_credential_available - = trash_credential_readable (esxi_credential); - } - else if (esxi_credential) - { - credential_t found; - - esxi_name = credential_name (esxi_credential); - esxi_uuid = credential_uuid (esxi_credential); - if (find_credential_with_permission - (esxi_uuid, - &found, - "get_credentials")) - abort (); - esxi_credential_available = (found > 0); + if (get_targets_data->get.trash + && target_iterator_esxi_trash (&targets)) + { + esxi_name + = trash_credential_name (esxi_credential); + esxi_uuid + = trash_credential_uuid (esxi_credential); + esxi_credential_available + = trash_credential_readable (esxi_credential); + } + else + { + credential_t found; + + esxi_name = credential_name (esxi_credential); + esxi_uuid = credential_uuid (esxi_credential); + if (find_credential_with_permission (esxi_uuid, + &found, + "get_credentials")) + abort (); + esxi_credential_available = (found > 0); + } } else { esxi_name = NULL; esxi_uuid = NULL; } + snmp_credential_available = 1; - if (get_targets_data->get.trash - && target_iterator_snmp_trash (&targets)) + if (snmp_credential) { - snmp_name - = trash_credential_name (snmp_credential); - snmp_uuid - = trash_credential_uuid (snmp_credential); - snmp_credential_available - = trash_credential_readable (snmp_credential); - } - else if (snmp_credential) - { - credential_t found; - - snmp_name = credential_name (snmp_credential); - snmp_uuid = credential_uuid (snmp_credential); - if (find_credential_with_permission - (snmp_uuid, - &found, - "get_credentials")) - abort (); - snmp_credential_available = (found > 0); + if (get_targets_data->get.trash + && target_iterator_snmp_trash (&targets)) + { + snmp_name + = trash_credential_name (snmp_credential); + snmp_uuid + = trash_credential_uuid (snmp_credential); + snmp_credential_available + = trash_credential_readable (snmp_credential); + } + else + { + credential_t found; + + snmp_name = credential_name (snmp_credential); + snmp_uuid = credential_uuid (snmp_credential); + if (find_credential_with_permission (snmp_uuid, + &found, + "get_credentials")) + abort (); + snmp_credential_available = (found > 0); + } } else { snmp_name = NULL; snmp_uuid = NULL; } + ssh_elevate_credential_available = 1; - if (get_targets_data->get.trash - && target_iterator_ssh_elevate_trash (&targets)) + if (ssh_elevate_credential) { - ssh_elevate_name - = trash_credential_name (ssh_elevate_credential); - ssh_elevate_uuid - = trash_credential_uuid (ssh_elevate_credential); - ssh_elevate_credential_available - = trash_credential_readable (ssh_elevate_credential); - } - else if (ssh_elevate_credential) - { - credential_t found; - - ssh_elevate_name = credential_name (ssh_elevate_credential); - ssh_elevate_uuid = credential_uuid (ssh_elevate_credential); - if (find_credential_with_permission - (ssh_elevate_uuid, - &found, - "get_credentials")) - abort (); - ssh_elevate_credential_available = (found > 0); + if (get_targets_data->get.trash + && target_iterator_ssh_elevate_trash (&targets)) + { + ssh_elevate_name + = trash_credential_name (ssh_elevate_credential); + ssh_elevate_uuid + = trash_credential_uuid (ssh_elevate_credential); + ssh_elevate_credential_available + = trash_credential_readable (ssh_elevate_credential); + } + else + { + credential_t found; + + ssh_elevate_name = credential_name (ssh_elevate_credential); + ssh_elevate_uuid = credential_uuid (ssh_elevate_credential); + if (find_credential_with_permission (ssh_elevate_uuid, + &found, + "get_credentials")) + abort (); + ssh_elevate_credential_available = (found > 0); + } } else { ssh_elevate_name = NULL; ssh_elevate_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); diff --git a/src/manage.h b/src/manage.h index 30e0642bb..da5ed43f6 100644 --- a/src/manage.h +++ b/src/manage.h @@ -2185,6 +2185,10 @@ init_credential_iterator_one (iterator_t*, credential_t); int init_credential_iterator (iterator_t*, const get_data_t *); +int +init_credential_iterator_format (iterator_t*, const get_data_t *, + credential_format_t); + const char* credential_iterator_login (iterator_t*); diff --git a/src/manage_sql.c b/src/manage_sql.c index 567d8ade6..8aa1b0a1f 100644 --- a/src/manage_sql.c +++ b/src/manage_sql.c @@ -36816,114 +36816,106 @@ delete_credential (const char *credential_id, int ultimate) /** * @brief LSC Credential iterator columns. */ -#define CREDENTIAL_ITERATOR_COLUMNS \ +#define CREDENTIAL_ITERATOR_COLUMNS_TABLE(table, lean) \ { \ - GET_ITERATOR_COLUMNS (credentials), \ + GET_ITERATOR_COLUMNS (table), \ /* public generic data */ \ { "type", NULL, KEYWORD_TYPE_STRING }, \ { "allow_insecure", NULL, KEYWORD_TYPE_INTEGER }, \ /* public type specific data */ \ - { "(SELECT value FROM credentials_data" \ - " WHERE credential = credentials.id AND type = 'username')", \ + { "(SELECT value FROM " table "_data" \ + " WHERE credential = " table ".id AND type = 'username')", \ "login", \ KEYWORD_TYPE_STRING \ }, \ - { "(SELECT value FROM credentials_data" \ - " WHERE credential = credentials.id AND type = 'certificate')", \ + { "(SELECT value FROM " table "_data" \ + " WHERE credential = " table ".id AND type = 'certificate')", \ NULL, \ KEYWORD_TYPE_STRING }, \ - { "(SELECT value FROM credentials_data" \ - " WHERE credential = credentials.id AND type = 'auth_algorithm')", \ + { "(CASE" \ + " WHEN type = 'snmp'" \ + " THEN (SELECT value FROM " table "_data" \ + " WHERE credential = " table ".id AND type = 'auth_algorithm')" \ + " ELSE ''" \ + " END)", \ NULL, \ KEYWORD_TYPE_STRING }, \ - { "(SELECT value FROM credentials_data" \ - " WHERE credential = credentials.id AND type = 'privacy_algorithm')", \ + { "(CASE" \ + " WHEN type = 'snmp'" \ + " THEN (SELECT value FROM " table "_data" \ + " WHERE credential = " table ".id AND type = 'privacy_algorithm')" \ + " ELSE ''" \ + " END)", \ NULL, \ KEYWORD_TYPE_STRING }, \ - { "(SELECT value FROM credentials_data" \ - " WHERE credential = credentials.id AND type = 'public_key')", \ + /* Only one used by credential_iterator_formats_xml (excl login, type) */ \ + { "(SELECT value FROM " table "_data" \ + " WHERE credential = " table ".id AND type = 'public_key')", \ NULL, \ KEYWORD_TYPE_STRING }, \ /* private data */ \ - { "(SELECT value FROM credentials_data" \ - " WHERE credential = credentials.id AND type = 'secret')", \ + { "(SELECT value FROM " table "_data" \ + " WHERE credential = " table ".id AND type = 'secret')", \ "secret", \ KEYWORD_TYPE_STRING }, \ - { "(SELECT value FROM credentials_data" \ - " WHERE credential = credentials.id AND type = 'password')", \ + { "(CASE" \ + " WHEN " lean \ + " THEN ''" \ + " ELSE (SELECT value FROM " table "_data" \ + " WHERE credential = " table ".id AND type = 'password')" \ + " END)", \ "password", \ KEYWORD_TYPE_STRING }, \ - { "(SELECT value FROM credentials_data" \ - " WHERE credential = credentials.id AND type = 'private_key')", \ + { "(CASE" \ + " WHEN " lean \ + " THEN ''" \ + " ELSE (SELECT value FROM " table "_data" \ + " WHERE credential = " table ".id AND type = 'private_key')" \ + " END)", \ "private_key", \ KEYWORD_TYPE_STRING }, \ - { "(SELECT value FROM credentials_data" \ - " WHERE credential = credentials.id AND type = 'community')", \ + { "(CASE" \ + " WHEN " lean \ + " THEN ''" \ + " ELSE (SELECT value FROM " table "_data" \ + " WHERE credential = " table ".id AND type = 'community')" \ + " END)", \ "community", \ KEYWORD_TYPE_STRING }, \ - { "(SELECT value FROM credentials_data" \ - " WHERE credential = credentials.id AND type = 'privacy_password')", \ + { "(CASE" \ + " WHEN " lean \ + " THEN ''" \ + " ELSE (SELECT value FROM " table "_data" \ + " WHERE credential = " table ".id AND type = 'privacy_password')" \ + " END)", \ "privacy_password", \ KEYWORD_TYPE_STRING }, \ { NULL, NULL, KEYWORD_TYPE_UNKNOWN } \ } +/** + * @brief LSC Credential iterator columns. + */ +#define CREDENTIAL_ITERATOR_COLUMNS \ + CREDENTIAL_ITERATOR_COLUMNS_TABLE("credentials", "FALSE") + /** * @brief LSC Credential iterator columns for trash case. */ -#define CREDENTIAL_ITERATOR_TRASH_COLUMNS \ - { \ - GET_ITERATOR_COLUMNS (credentials_trash), \ - /* public generic data */ \ - { "type", NULL, KEYWORD_TYPE_STRING }, \ - { "allow_insecure", NULL, KEYWORD_TYPE_INTEGER }, \ - /* public type specific data */ \ - { "(SELECT value FROM credentials_trash_data" \ - " WHERE credential = credentials_trash.id AND type = 'username')", \ - "login", \ - KEYWORD_TYPE_STRING }, \ - { "(SELECT value FROM credentials_trash_data" \ - " WHERE credential = credentials_trash.id AND type = 'certificate')", \ - NULL, \ - KEYWORD_TYPE_STRING }, \ - { "(SELECT value FROM credentials_trash_data" \ - " WHERE credential = credentials_trash.id" \ - " AND type = 'auth_algorithm')", \ - NULL, \ - KEYWORD_TYPE_STRING }, \ - { "(SELECT value FROM credentials_trash_data" \ - " WHERE credential = credentials_trash.id" \ - " AND type = 'privacy_algorithm')", \ - NULL, \ - KEYWORD_TYPE_STRING }, \ - { "(SELECT value FROM credentials_data" \ - " WHERE credential = credentials_trash.id AND type = 'public_key')", \ - NULL, \ - KEYWORD_TYPE_STRING }, \ - /* private data */ \ - { "(SELECT value FROM credentials_trash_data" \ - " WHERE credential = credentials_trash.id AND type = 'secret')", \ - "secret", \ - KEYWORD_TYPE_STRING }, \ - { "(SELECT value FROM credentials_trash_data" \ - " WHERE credential = credentials_trash.id AND type = 'password')", \ - "password", \ - KEYWORD_TYPE_STRING }, \ - { "(SELECT value FROM credentials_trash_data" \ - " WHERE credential = credentials_trash.id AND type = 'private_key')", \ - "private_key", \ - KEYWORD_TYPE_STRING }, \ - { "(SELECT value FROM credentials_trash_data" \ - " WHERE credential = credentials_trash.id AND type = 'community')", \ - "community", \ - KEYWORD_TYPE_STRING }, \ - { "(SELECT value FROM credentials_trash_data" \ - " WHERE credential = credentials_trash.id" \ - " AND type = 'privacy_password')", \ - "privacy_password", \ - KEYWORD_TYPE_STRING }, \ - { NULL, NULL, KEYWORD_TYPE_UNKNOWN } \ - } +#define CREDENTIAL_ITERATOR_TRASH_COLUMNS \ + CREDENTIAL_ITERATOR_COLUMNS_TABLE("credentials_trash", "FALSE") + +/** + * @brief LSC Credential iterator columns. + */ +#define CREDENTIAL_ITERATOR_LEAN_COLUMNS \ + CREDENTIAL_ITERATOR_COLUMNS_TABLE("credentials", "TRUE") + +/** + * @brief LSC Credential iterator columns for trash case. + */ +#define CREDENTIAL_ITERATOR_LEAN_TRASH_COLUMNS \ + CREDENTIAL_ITERATOR_COLUMNS_TABLE("credentials_trash", "TRUE") /** * @brief Count number of LSC Credentials. @@ -37411,6 +37403,47 @@ init_credential_iterator (iterator_t* iterator, const get_data_t *get) TRUE); } +/** + * @brief Initialise a Credential iterator, where the format is known. + * + * @param[in] iterator Iterator. + * @param[in] get GET data. + * @param[in] format Credential format. + * + * @return 0 success, 1 failed to find filter, 2 failed to find + * filter (filt_id), -1 error. + */ +int +init_credential_iterator_format (iterator_t* iterator, const get_data_t *get, + credential_format_t format) +{ + static const char *filter_columns[] = CREDENTIAL_ITERATOR_FILTER_COLUMNS; + static column_t columns[] = CREDENTIAL_ITERATOR_COLUMNS; + static column_t trash_columns[] = CREDENTIAL_ITERATOR_TRASH_COLUMNS; + static column_t lean_columns[] = CREDENTIAL_ITERATOR_LEAN_COLUMNS; + static column_t lean_trash_columns[] = CREDENTIAL_ITERATOR_LEAN_TRASH_COLUMNS; + column_t *actual_columns, *actual_trash_columns; + + actual_columns = columns; + actual_trash_columns = trash_columns; + if (format == CREDENTIAL_FORMAT_NONE) + { + actual_columns = lean_columns; + actual_trash_columns = lean_trash_columns; + } + + return init_get_iterator (iterator, + "credential", + get, + actual_columns, + actual_trash_columns, + filter_columns, + 0, + NULL, + NULL, + TRUE); +} + /** * @brief Get possibly encrypted data from credentials. * @@ -37426,13 +37459,16 @@ credential_iterator_encrypted_data (iterator_t* iterator, const char* type) if (iterator->done) return NULL; + secret = iterator_string (iterator, GET_ITERATOR_COLUMN_COUNT + 7); + if (type == NULL) { g_warning ("%s: NULL data type given", __func__); return NULL; } - else if (strcmp (type, "password") == 0) + + if (strcmp (type, "password") == 0) unencrypted = iterator_string (iterator, GET_ITERATOR_COLUMN_COUNT + 8); else if (strcmp (type, "private_key") == 0) unencrypted = iterator_string (iterator, GET_ITERATOR_COLUMN_COUNT + 9); @@ -37445,11 +37481,13 @@ credential_iterator_encrypted_data (iterator_t* iterator, const char* type) g_warning ("%s: unknown data type \"%s\"", __func__, type); return NULL; } + /* If we do not have a private key, there is no encrypted data. - Return the password as is or NULL. */ + * Return the password as is or NULL. */ + if (secret) { - /* This is an encrypted credential. */ + /* This is an encrypted credential. */ if (!iterator->crypt_ctx) { char *encryption_key_uid = current_encryption_key_uid (TRUE); @@ -37459,10 +37497,54 @@ credential_iterator_encrypted_data (iterator_t* iterator, const char* type) return lsc_crypt_decrypt (iterator->crypt_ctx, secret, type); } + + return unencrypted; +} + +/** + * @brief Check whether possibly encrypted data exists. + * + * @param[in] iterator Iterator. + * @param[in] type Type of data. + * + * @return -1 if error, 1 if exists, else 0. + */ +static int +credential_iterator_encrypted_data_exists (iterator_t* iterator, const char* type) +{ + const char *secret, *unencrypted; + + if (iterator->done) + return -1; + + secret = iterator_string (iterator, GET_ITERATOR_COLUMN_COUNT + 7); + + if (type == NULL) + { + g_warning ("%s: NULL data type given", __func__); + return -1; + } + + if (strcmp (type, "password") == 0) + unencrypted = iterator_string (iterator, GET_ITERATOR_COLUMN_COUNT + 8); + else if (strcmp (type, "private_key") == 0) + unencrypted = iterator_string (iterator, GET_ITERATOR_COLUMN_COUNT + 9); + else if (strcmp (type, "community") == 0) + unencrypted = iterator_string (iterator, GET_ITERATOR_COLUMN_COUNT + 10); + else if (strcmp (type, "privacy_password") == 0) + unencrypted = iterator_string (iterator, GET_ITERATOR_COLUMN_COUNT + 11); else { - return unencrypted; + g_warning ("%s: unknown data type \"%s\"", __func__, type); + return -1; } + + /* If we do not have a private key, there is no encrypted data. */ + + if (secret) + return 1; + + return unencrypted ? 1 : 0; } /** @@ -37569,6 +37651,19 @@ credential_iterator_private_key (iterator_t* iterator) return credential_iterator_encrypted_data (iterator, "private_key"); } +/** + * @brief Check whether the private_key from a Credential iterator exists. + * + * @param[in] iterator Iterator. + * + * @return -1 if error, 1 if exists, else 0. + */ +static int +credential_iterator_private_key_exists (iterator_t* iterator) +{ + return credential_iterator_encrypted_data_exists (iterator, "private_key"); +} + /** * @brief Get the SNMP community from a Credential iterator. @@ -37742,36 +37837,32 @@ gboolean credential_iterator_format_available (iterator_t* iterator, credential_format_t format) { - const char *type, *login, *private_key; + const char *type, *login; + + if (format == CREDENTIAL_FORMAT_NONE) + return TRUE; + + if (format == CREDENTIAL_FORMAT_ERROR) + return FALSE; type = credential_iterator_type (iterator); login = credential_iterator_login (iterator); - private_key = credential_iterator_private_key (iterator); - switch (format) - { - case CREDENTIAL_FORMAT_NONE: - return TRUE; - case CREDENTIAL_FORMAT_KEY: - case CREDENTIAL_FORMAT_RPM: - case CREDENTIAL_FORMAT_DEB: - if (strcasecmp (type, "usk") == 0 && private_key) - return validate_credential_username_for_format (login, format); - else - return FALSE; - case CREDENTIAL_FORMAT_EXE: - if (strcasecmp (type, "up") == 0) - return validate_credential_username_for_format (login, format); - else - return FALSE; - case CREDENTIAL_FORMAT_PEM: - if (strcasecmp (type, "cc") == 0) - return validate_credential_username_for_format (login, format); - else - return FALSE; - case CREDENTIAL_FORMAT_ERROR: - return FALSE; - } + if (format == CREDENTIAL_FORMAT_EXE + && strcasecmp (type, "up") == 0) + return validate_credential_username_for_format (login, format); + + if (format == CREDENTIAL_FORMAT_PEM + && strcasecmp (type, "cc") == 0) + return validate_credential_username_for_format (login, format); + + if ((format == CREDENTIAL_FORMAT_KEY + || format == CREDENTIAL_FORMAT_RPM + || format == CREDENTIAL_FORMAT_DEB) + && strcasecmp (type, "usk") == 0 + && credential_iterator_private_key_exists (iterator)) + return validate_credential_username_for_format (login, format); + return FALSE; }