From 88c2bffb35b16a54de4fd54af66fb66370c8f0e7 Mon Sep 17 00:00:00 2001 From: Matt Mundell Date: Tue, 2 Jan 2024 19:39:30 +0200 Subject: [PATCH 1/9] Change: Check trash target references before accessing In the trash case of GET_TARGETS check that dependent resources like credentials exist before trying to access info about them. This speeds up the GSA trashcan, by skipping some SQL queries that would always return NULL. --- src/gmp.c | 218 +++++++++++++++++++++++++++++------------------------- 1 file changed, 117 insertions(+), 101 deletions(-) diff --git a/src/gmp.c b/src/gmp.c index 17f2335e5..009352ef4 100644 --- a/src/gmp.c +++ b/src/gmp.c @@ -16956,147 +16956,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)) - { - 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) + 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)) - { - 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) + 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)) - { - 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) + 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)) - { - 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) + 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)) - { - 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) + 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); From decd117c83eaead5e30afa3a73439757b3beee99 Mon Sep 17 00:00:00 2001 From: Matt Mundell Date: Mon, 8 Jan 2024 16:16:33 +0200 Subject: [PATCH 2/9] Move variables to where they are used --- src/gmp.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/gmp.c b/src/gmp.c index 009352ef4..9599fbc6a 100644 --- a/src/gmp.c +++ b/src/gmp.c @@ -12163,7 +12163,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, @@ -12177,8 +12177,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); @@ -12257,6 +12255,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 @@ -12265,8 +12267,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 From 4d55aa06ba68633d14d6e74eea34635c982458aa Mon Sep 17 00:00:00 2001 From: Matt Mundell Date: Mon, 8 Jan 2024 16:51:29 +0200 Subject: [PATCH 3/9] Combine CREDENTIAL_ITERATOR_COLUMNS and CREDENTIAL_ITERATOR_TRASH_COLUMNS --- src/manage_sql.c | 105 ++++++++++++++--------------------------------- 1 file changed, 30 insertions(+), 75 deletions(-) diff --git a/src/manage_sql.c b/src/manage_sql.c index 0b3ce888c..4a5813826 100644 --- a/src/manage_sql.c +++ b/src/manage_sql.c @@ -36788,114 +36788,69 @@ delete_credential (const char *credential_id, int ultimate) /** * @brief LSC Credential iterator columns. */ -#define CREDENTIAL_ITERATOR_COLUMNS \ +#define CREDENTIAL_ITERATOR_COLUMNS_TABLE(table) \ { \ - 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')", \ + { "(SELECT value FROM " table "_data" \ + " WHERE credential = " table ".id AND type = 'auth_algorithm')", \ NULL, \ KEYWORD_TYPE_STRING }, \ - { "(SELECT value FROM credentials_data" \ - " WHERE credential = credentials.id AND type = 'privacy_algorithm')", \ + { "(SELECT value FROM " table "_data" \ + " WHERE credential = " table ".id AND type = 'privacy_algorithm')", \ NULL, \ KEYWORD_TYPE_STRING }, \ - { "(SELECT value FROM credentials_data" \ - " WHERE credential = credentials.id AND type = 'public_key')", \ + { "(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')", \ + { "(SELECT value FROM " table "_data" \ + " WHERE credential = " table ".id AND type = 'password')", \ "password", \ KEYWORD_TYPE_STRING }, \ - { "(SELECT value FROM credentials_data" \ - " WHERE credential = credentials.id AND type = 'private_key')", \ + { "(SELECT value FROM " table "_data" \ + " WHERE credential = " table ".id AND type = 'private_key')", \ "private_key", \ KEYWORD_TYPE_STRING }, \ - { "(SELECT value FROM credentials_data" \ - " WHERE credential = credentials.id AND type = 'community')", \ + { "(SELECT value FROM " table "_data" \ + " WHERE credential = " table ".id AND type = 'community')", \ "community", \ KEYWORD_TYPE_STRING }, \ - { "(SELECT value FROM credentials_data" \ - " WHERE credential = credentials.id AND type = 'privacy_password')", \ + { "(SELECT value FROM " table "_data" \ + " WHERE credential = " table ".id AND type = 'privacy_password')", \ "privacy_password", \ KEYWORD_TYPE_STRING }, \ { NULL, NULL, KEYWORD_TYPE_UNKNOWN } \ } +/** + * @brief LSC Credential iterator columns. + */ +#define CREDENTIAL_ITERATOR_COLUMNS \ +CREDENTIAL_ITERATOR_COLUMNS_TABLE("credentials") + /** * @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") /** * @brief Count number of LSC Credentials. From 15661bf1b0150ea954660bb7fc11e45f8a2857f3 Mon Sep 17 00:00:00 2001 From: Matt Mundell Date: Tue, 9 Jan 2024 14:21:39 +0200 Subject: [PATCH 4/9] Make credential_iterator_format_available variable use more obvious --- src/manage_sql.c | 46 ++++++++++++++++++++++------------------------ 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/src/manage_sql.c b/src/manage_sql.c index 4a5813826..9df36c12a 100644 --- a/src/manage_sql.c +++ b/src/manage_sql.c @@ -37671,34 +37671,32 @@ credential_iterator_format_available (iterator_t* iterator, { const char *type, *login, *private_key; + if (format == CREDENTIAL_FORMAT_NONE) + return TRUE; + + if (format == CREDENTIAL_FORMAT_ERROR) + return FALSE; + type = credential_iterator_type (iterator); login = credential_iterator_login (iterator); + + 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); + 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_KEY + || format == CREDENTIAL_FORMAT_RPM + || format == CREDENTIAL_FORMAT_DEB) + && strcasecmp (type, "usk") == 0 + && private_key) + return validate_credential_username_for_format (login, format); + return FALSE; } From 222f9aa07c980658bf461f241566c6510e627153 Mon Sep 17 00:00:00 2001 From: Matt Mundell Date: Tue, 9 Jan 2024 14:39:23 +0200 Subject: [PATCH 5/9] Note credential iterator field use --- src/manage_sql.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/manage_sql.c b/src/manage_sql.c index 9df36c12a..318a36397 100644 --- a/src/manage_sql.c +++ b/src/manage_sql.c @@ -36812,6 +36812,7 @@ delete_credential (const char *credential_id, int ultimate) " WHERE credential = " table ".id AND type = 'privacy_algorithm')", \ NULL, \ KEYWORD_TYPE_STRING }, \ + /* 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, \ From fc8765d4758b466c1adb7121770af85d9832e593 Mon Sep 17 00:00:00 2001 From: Matt Mundell Date: Tue, 9 Jan 2024 15:53:47 +0200 Subject: [PATCH 6/9] Change: Use fewer queries in credential iterator when possible --- src/gmp.c | 5 +- src/manage.h | 4 ++ src/manage_sql.c | 119 +++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 107 insertions(+), 21 deletions(-) diff --git a/src/gmp.c b/src/gmp.c index 9599fbc6a..217826c8e 100644 --- a/src/gmp.c +++ b/src/gmp.c @@ -12124,8 +12124,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) diff --git a/src/manage.h b/src/manage.h index 77977728e..82595adaf 100644 --- a/src/manage.h +++ b/src/manage.h @@ -2183,6 +2183,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 318a36397..5ae9078e0 100644 --- a/src/manage_sql.c +++ b/src/manage_sql.c @@ -36788,7 +36788,7 @@ delete_credential (const char *credential_id, int ultimate) /** * @brief LSC Credential iterator columns. */ -#define CREDENTIAL_ITERATOR_COLUMNS_TABLE(table) \ +#define CREDENTIAL_ITERATOR_COLUMNS_TABLE(table, lean) \ { \ GET_ITERATOR_COLUMNS (table), \ /* public generic data */ \ @@ -36804,12 +36804,20 @@ delete_credential (const char *credential_id, int ultimate) " WHERE credential = " table ".id AND type = 'certificate')", \ NULL, \ KEYWORD_TYPE_STRING }, \ - { "(SELECT value FROM " table "_data" \ - " WHERE credential = " table ".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 " table "_data" \ - " WHERE credential = " table ".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 }, \ /* Only one used by credential_iterator_formats_xml (excl login, type) */ \ @@ -36818,24 +36826,44 @@ delete_credential (const char *credential_id, int ultimate) NULL, \ KEYWORD_TYPE_STRING }, \ /* private data */ \ - { "(SELECT value FROM " table "_data" \ - " WHERE credential = " table ".id AND type = 'secret')", \ + { "(CASE" \ + " WHEN " lean \ + " THEN ''" \ + " ELSE (SELECT value FROM " table "_data" \ + " WHERE credential = " table ".id AND type = 'secret')" \ + " END)", \ "secret", \ KEYWORD_TYPE_STRING }, \ - { "(SELECT value FROM " table "_data" \ - " WHERE credential = " table ".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 " table "_data" \ - " WHERE credential = " table ".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 " table "_data" \ - " WHERE credential = " table ".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 " table "_data" \ - " WHERE credential = " table ".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 } \ @@ -36844,14 +36872,26 @@ delete_credential (const char *credential_id, int ultimate) /** * @brief LSC Credential iterator columns. */ -#define CREDENTIAL_ITERATOR_COLUMNS \ -CREDENTIAL_ITERATOR_COLUMNS_TABLE("credentials") +#define CREDENTIAL_ITERATOR_COLUMNS \ + CREDENTIAL_ITERATOR_COLUMNS_TABLE("credentials", "FALSE") + +/** + * @brief LSC Credential iterator columns for trash case. + */ +#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_TRASH_COLUMNS \ -CREDENTIAL_ITERATOR_COLUMNS_TABLE("credentials_trash") +#define CREDENTIAL_ITERATOR_LEAN_TRASH_COLUMNS \ + CREDENTIAL_ITERATOR_COLUMNS_TABLE("credentials_trash", "TRUE") /** * @brief Count number of LSC Credentials. @@ -37339,6 +37379,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. * From 45987b599c0abc3bacff769b7b981335f6d2d0e5 Mon Sep 17 00:00:00 2001 From: Matt Mundell Date: Fri, 8 Mar 2024 17:05:06 +0200 Subject: [PATCH 7/9] Remove secret from lean as it is needed by credential_iterator_private_key --- src/manage_sql.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/manage_sql.c b/src/manage_sql.c index 516e8d22c..54e7bf17f 100644 --- a/src/manage_sql.c +++ b/src/manage_sql.c @@ -36846,12 +36846,8 @@ delete_credential (const char *credential_id, int ultimate) NULL, \ KEYWORD_TYPE_STRING }, \ /* private data */ \ - { "(CASE" \ - " WHEN " lean \ - " THEN ''" \ - " ELSE (SELECT value FROM " table "_data" \ - " WHERE credential = " table ".id AND type = 'secret')" \ - " END)", \ + { "(SELECT value FROM " table "_data" \ + " WHERE credential = " table ".id AND type = 'secret')", \ "secret", \ KEYWORD_TYPE_STRING }, \ { "(CASE" \ From e220ab315c9f72973f250cf2863a56ef522a64bb Mon Sep 17 00:00:00 2001 From: Matt Mundell Date: Fri, 8 Mar 2024 17:05:27 +0200 Subject: [PATCH 8/9] Remove redundant elses --- src/manage_sql.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/manage_sql.c b/src/manage_sql.c index 54e7bf17f..b6688caf7 100644 --- a/src/manage_sql.c +++ b/src/manage_sql.c @@ -37451,13 +37451,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); @@ -37470,11 +37473,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); @@ -37484,10 +37489,8 @@ credential_iterator_encrypted_data (iterator_t* iterator, const char* type) return lsc_crypt_decrypt (iterator->crypt_ctx, secret, type); } - else - { - return unencrypted; - } + + return unencrypted; } /** From e919778988ed07bdbdff56d8cc0b52993aa68dfb Mon Sep 17 00:00:00 2001 From: Matt Mundell Date: Fri, 8 Mar 2024 17:06:15 +0200 Subject: [PATCH 9/9] Use existance check for private key in credential_iterator_format_available --- src/manage_sql.c | 65 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 61 insertions(+), 4 deletions(-) diff --git a/src/manage_sql.c b/src/manage_sql.c index b6688caf7..a8c31e925 100644 --- a/src/manage_sql.c +++ b/src/manage_sql.c @@ -37493,6 +37493,52 @@ credential_iterator_encrypted_data (iterator_t* iterator, const char* 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 + { + 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; +} + /** * @brief Get the login from a Credential iterator. * @@ -37597,6 +37643,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. @@ -37770,7 +37829,7 @@ 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; @@ -37789,13 +37848,11 @@ credential_iterator_format_available (iterator_t* iterator, && strcasecmp (type, "cc") == 0) return validate_credential_username_for_format (login, format); - private_key = credential_iterator_private_key (iterator); - if ((format == CREDENTIAL_FORMAT_KEY || format == CREDENTIAL_FORMAT_RPM || format == CREDENTIAL_FORMAT_DEB) && strcasecmp (type, "usk") == 0 - && private_key) + && credential_iterator_private_key_exists (iterator)) return validate_credential_username_for_format (login, format); return FALSE;