diff --git a/src/knownhosts.c b/src/knownhosts.c index 4816bb41..b17258b0 100644 --- a/src/knownhosts.c +++ b/src/knownhosts.c @@ -216,11 +216,22 @@ ssh_known_hosts_entries_compare(struct ssh_knownhosts_entry *k1, return 0; } -/* This method reads the known_hosts file referenced by the path +/** + * @internal + * + * @brief Read entries from filename to provided list + * + * This method reads the known_hosts file referenced by the path * in filename argument, and entries matching the match argument * will be added to the list in entries argument. * If the entries list is NULL, it will allocate a new list. Caller * is responsible to free it even if an error occurs. + * + * @param match[in] The host name (with port) to match against + * @param filename[in] The known hosts file to parse + * @param entries[in,out] The list of entries to append matching ones + * @return `SSH_OK` on missing file or success parsing, + * `SSH_ERROR` on error */ static int ssh_known_hosts_read_entries(const char *match, const char *filename, @@ -346,6 +357,33 @@ static char *ssh_session_get_host_port(ssh_session session) /** * @internal + * + * @brief Free known hosts entries list + * + * @param[in] entry_list The list of ssh_knownhosts_entry items + */ +static void ssh_knownhosts_entries_free(struct ssh_list *entry_list) +{ + struct ssh_iterator *it = NULL; + + if (entry_list == NULL) { + return; + } + + for (it = ssh_list_get_iterator(entry_list); + it != NULL; + it = ssh_list_get_iterator(entry_list)) { + struct ssh_knownhosts_entry *entry = NULL; + + entry = ssh_iterator_value(struct ssh_knownhosts_entry *, it); + ssh_knownhosts_entry_free(entry); + ssh_list_remove(entry_list, it); + } + ssh_list_free(entry_list); +} +/** + * @internal + * * @brief Check which host keys should be preferred for the session. * * This checks the known_hosts file to find out which algorithms should be @@ -453,7 +491,7 @@ struct ssh_list *ssh_known_hosts_get_algorithms(ssh_session session) return list; error: - ssh_list_free(entry_list); + ssh_knownhosts_entries_free(entry_list); ssh_list_free(list); return NULL; } @@ -505,6 +543,7 @@ static const char *ssh_known_host_sigs_from_hostkey_type(enum ssh_keytypes_e typ /** * @internal + * * @brief Get the host keys algorithms identifiers from the known_hosts files * * This expands the signatures types that can be generated from the keys types @@ -549,7 +588,7 @@ char *ssh_known_hosts_get_algorithms_names(ssh_session session) &entry_list); if (rc != 0) { SAFE_FREE(host_port); - ssh_list_free(entry_list); + ssh_knownhosts_entries_free(entry_list); return NULL; } @@ -558,7 +597,7 @@ char *ssh_known_hosts_get_algorithms_names(ssh_session session) &entry_list); SAFE_FREE(host_port); if (rc != 0) { - ssh_list_free(entry_list); + ssh_knownhosts_entries_free(entry_list); return NULL; } @@ -799,7 +838,6 @@ out: enum ssh_known_hosts_e ssh_session_has_known_hosts_entry(ssh_session session) { struct ssh_list *entry_list = NULL; - struct ssh_iterator *it = NULL; char *host_port = NULL; bool global_known_hosts_found = false; bool known_hosts_found = false; @@ -860,7 +898,7 @@ enum ssh_known_hosts_e ssh_session_has_known_hosts_entry(ssh_session session) &entry_list); if (rc != 0) { SAFE_FREE(host_port); - ssh_list_free(entry_list); + ssh_knownhosts_entries_free(entry_list); return SSH_KNOWN_HOSTS_ERROR; } } @@ -871,7 +909,7 @@ enum ssh_known_hosts_e ssh_session_has_known_hosts_entry(ssh_session session) &entry_list); if (rc != 0) { SAFE_FREE(host_port); - ssh_list_free(entry_list); + ssh_knownhosts_entries_free(entry_list); return SSH_KNOWN_HOSTS_ERROR; } } @@ -883,16 +921,7 @@ enum ssh_known_hosts_e ssh_session_has_known_hosts_entry(ssh_session session) return SSH_KNOWN_HOSTS_UNKNOWN; } - for (it = ssh_list_get_iterator(entry_list); - it != NULL; - it = ssh_list_get_iterator(entry_list)) { - struct ssh_knownhosts_entry *entry = NULL; - - entry = ssh_iterator_value(struct ssh_knownhosts_entry *, it); - ssh_knownhosts_entry_free(entry); - ssh_list_remove(entry_list, it); - } - ssh_list_free(entry_list); + ssh_knownhosts_entries_free(entry_list); return SSH_KNOWN_HOSTS_OK; } @@ -1079,13 +1108,13 @@ ssh_known_hosts_check_server_key(const char *hosts_entry, filename, &entry_list); if (rc != 0) { - ssh_list_free(entry_list); + ssh_knownhosts_entries_free(entry_list); return SSH_KNOWN_HOSTS_UNKNOWN; } it = ssh_list_get_iterator(entry_list); if (it == NULL) { - ssh_list_free(entry_list); + ssh_knownhosts_entries_free(entry_list); return SSH_KNOWN_HOSTS_UNKNOWN; } @@ -1115,16 +1144,7 @@ ssh_known_hosts_check_server_key(const char *hosts_entry, } } - for (it = ssh_list_get_iterator(entry_list); - it != NULL; - it = ssh_list_get_iterator(entry_list)) { - struct ssh_knownhosts_entry *entry = NULL; - - entry = ssh_iterator_value(struct ssh_knownhosts_entry *, it); - ssh_knownhosts_entry_free(entry); - ssh_list_remove(entry_list, it); - } - ssh_list_free(entry_list); + ssh_knownhosts_entries_free(entry_list); return found; } @@ -1196,6 +1216,8 @@ ssh_session_get_known_hosts_entry(ssh_session session, } /** + * @internal + * * @brief Get the known_hosts entry for the current connected session * from the given known_hosts file. *