mirror of
https://git.libssh.org/projects/libssh.git
synced 2026-02-04 12:20:42 +09:00
Compare commits
3 Commits
b2abcf8534
...
1b3c061aae
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1b3c061aae | ||
|
|
1525ea3dda | ||
|
|
a189c2ef4d |
@@ -850,6 +850,10 @@ int ssh_gssapi_client_identity(ssh_session session, gss_OID_set *valid_oids)
|
|||||||
char *ptr = NULL;
|
char *ptr = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (session == NULL || session->gssapi == NULL) {
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
if (session->gssapi->client.client_deleg_creds == NULL) {
|
if (session->gssapi->client.client_deleg_creds == NULL) {
|
||||||
if (session->opts.gss_client_identity != NULL) {
|
if (session->opts.gss_client_identity != NULL) {
|
||||||
namebuf.value = (void *)session->opts.gss_client_identity;
|
namebuf.value = (void *)session->opts.gss_client_identity;
|
||||||
|
|||||||
@@ -216,11 +216,22 @@ ssh_known_hosts_entries_compare(struct ssh_knownhosts_entry *k1,
|
|||||||
return 0;
|
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
|
* in filename argument, and entries matching the match argument
|
||||||
* will be added to the list in entries argument.
|
* will be added to the list in entries argument.
|
||||||
* If the entries list is NULL, it will allocate a new list. Caller
|
* If the entries list is NULL, it will allocate a new list. Caller
|
||||||
* is responsible to free it even if an error occurs.
|
* 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,
|
static int ssh_known_hosts_read_entries(const char *match,
|
||||||
const char *filename,
|
const char *filename,
|
||||||
@@ -346,6 +357,33 @@ static char *ssh_session_get_host_port(ssh_session session)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @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.
|
* @brief Check which host keys should be preferred for the session.
|
||||||
*
|
*
|
||||||
* This checks the known_hosts file to find out which algorithms should be
|
* 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;
|
return list;
|
||||||
error:
|
error:
|
||||||
ssh_list_free(entry_list);
|
ssh_knownhosts_entries_free(entry_list);
|
||||||
ssh_list_free(list);
|
ssh_list_free(list);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -505,6 +543,7 @@ static const char *ssh_known_host_sigs_from_hostkey_type(enum ssh_keytypes_e typ
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
|
*
|
||||||
* @brief Get the host keys algorithms identifiers from the known_hosts files
|
* @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
|
* 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);
|
&entry_list);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
SAFE_FREE(host_port);
|
SAFE_FREE(host_port);
|
||||||
ssh_list_free(entry_list);
|
ssh_knownhosts_entries_free(entry_list);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -558,7 +597,7 @@ char *ssh_known_hosts_get_algorithms_names(ssh_session session)
|
|||||||
&entry_list);
|
&entry_list);
|
||||||
SAFE_FREE(host_port);
|
SAFE_FREE(host_port);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
ssh_list_free(entry_list);
|
ssh_knownhosts_entries_free(entry_list);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -799,7 +838,6 @@ out:
|
|||||||
enum ssh_known_hosts_e ssh_session_has_known_hosts_entry(ssh_session session)
|
enum ssh_known_hosts_e ssh_session_has_known_hosts_entry(ssh_session session)
|
||||||
{
|
{
|
||||||
struct ssh_list *entry_list = NULL;
|
struct ssh_list *entry_list = NULL;
|
||||||
struct ssh_iterator *it = NULL;
|
|
||||||
char *host_port = NULL;
|
char *host_port = NULL;
|
||||||
bool global_known_hosts_found = false;
|
bool global_known_hosts_found = false;
|
||||||
bool 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);
|
&entry_list);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
SAFE_FREE(host_port);
|
SAFE_FREE(host_port);
|
||||||
ssh_list_free(entry_list);
|
ssh_knownhosts_entries_free(entry_list);
|
||||||
return SSH_KNOWN_HOSTS_ERROR;
|
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);
|
&entry_list);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
SAFE_FREE(host_port);
|
SAFE_FREE(host_port);
|
||||||
ssh_list_free(entry_list);
|
ssh_knownhosts_entries_free(entry_list);
|
||||||
return SSH_KNOWN_HOSTS_ERROR;
|
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;
|
return SSH_KNOWN_HOSTS_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (it = ssh_list_get_iterator(entry_list);
|
ssh_knownhosts_entries_free(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);
|
|
||||||
|
|
||||||
return SSH_KNOWN_HOSTS_OK;
|
return SSH_KNOWN_HOSTS_OK;
|
||||||
}
|
}
|
||||||
@@ -1079,13 +1108,13 @@ ssh_known_hosts_check_server_key(const char *hosts_entry,
|
|||||||
filename,
|
filename,
|
||||||
&entry_list);
|
&entry_list);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
ssh_list_free(entry_list);
|
ssh_knownhosts_entries_free(entry_list);
|
||||||
return SSH_KNOWN_HOSTS_UNKNOWN;
|
return SSH_KNOWN_HOSTS_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
it = ssh_list_get_iterator(entry_list);
|
it = ssh_list_get_iterator(entry_list);
|
||||||
if (it == NULL) {
|
if (it == NULL) {
|
||||||
ssh_list_free(entry_list);
|
ssh_knownhosts_entries_free(entry_list);
|
||||||
return SSH_KNOWN_HOSTS_UNKNOWN;
|
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);
|
ssh_knownhosts_entries_free(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);
|
|
||||||
|
|
||||||
return found;
|
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
|
* @brief Get the known_hosts entry for the current connected session
|
||||||
* from the given known_hosts file.
|
* from the given known_hosts file.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -696,6 +696,82 @@ static void torture_knownhosts_algorithms_global(void **state)
|
|||||||
ssh_free(session);
|
ssh_free(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int setup_bad_knownhosts_file(void **state)
|
||||||
|
{
|
||||||
|
char *tmp_file = NULL;
|
||||||
|
size_t nwritten;
|
||||||
|
FILE *fp = NULL;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
tmp_file = torture_create_temp_file(TMP_FILE_NAME);
|
||||||
|
assert_non_null(tmp_file);
|
||||||
|
|
||||||
|
*state = tmp_file;
|
||||||
|
|
||||||
|
fp = fopen(tmp_file, "w");
|
||||||
|
assert_non_null(fp);
|
||||||
|
|
||||||
|
nwritten = fwrite(LOCALHOST_DEFAULT_ED25519,
|
||||||
|
sizeof(char),
|
||||||
|
strlen(LOCALHOST_DEFAULT_ED25519),
|
||||||
|
fp);
|
||||||
|
if (nwritten != strlen(LOCALHOST_DEFAULT_ED25519)) {
|
||||||
|
rc = -1;
|
||||||
|
goto close_fp;
|
||||||
|
}
|
||||||
|
|
||||||
|
nwritten = fwrite("\n", sizeof(char), 1, fp);
|
||||||
|
if (nwritten != 1) {
|
||||||
|
rc = -1;
|
||||||
|
goto close_fp;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define LOCALHOST_BAD_LINE "localhost \n"
|
||||||
|
nwritten = fwrite(LOCALHOST_BAD_LINE,
|
||||||
|
sizeof(char),
|
||||||
|
strlen(LOCALHOST_BAD_LINE),
|
||||||
|
fp);
|
||||||
|
if (nwritten != strlen(LOCALHOST_BAD_LINE)) {
|
||||||
|
rc = -1;
|
||||||
|
goto close_fp;
|
||||||
|
}
|
||||||
|
|
||||||
|
close_fp:
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void torture_knownhosts_has_entry(void **state)
|
||||||
|
{
|
||||||
|
const char *knownhosts_file = *state;
|
||||||
|
enum ssh_known_hosts_e found;
|
||||||
|
ssh_session session;
|
||||||
|
bool process_config = false;
|
||||||
|
struct ssh_knownhosts_entry *entry = NULL;
|
||||||
|
|
||||||
|
session = ssh_new();
|
||||||
|
assert_non_null(session);
|
||||||
|
|
||||||
|
/* This makes sure the global configuration file is not processed */
|
||||||
|
ssh_options_set(session, SSH_OPTIONS_PROCESS_CONFIG, &process_config);
|
||||||
|
|
||||||
|
ssh_options_set(session, SSH_OPTIONS_HOST, "localhost");
|
||||||
|
/* This makes sure the current-user's known hosts are not used */
|
||||||
|
ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, "/dev/null");
|
||||||
|
ssh_options_set(session, SSH_OPTIONS_GLOBAL_KNOWNHOSTS, knownhosts_file);
|
||||||
|
|
||||||
|
/* Error is expected -- this tests the memory is not leaked from this
|
||||||
|
* test case */
|
||||||
|
found = ssh_session_has_known_hosts_entry(session);
|
||||||
|
assert_int_equal(found, SSH_KNOWN_HOSTS_ERROR);
|
||||||
|
|
||||||
|
found = ssh_session_get_known_hosts_entry(session, &entry);
|
||||||
|
assert_int_equal(found, SSH_KNOWN_HOSTS_ERROR);
|
||||||
|
assert_null(entry);
|
||||||
|
|
||||||
|
ssh_free(session);
|
||||||
|
}
|
||||||
#endif /* _WIN32 There is no /dev/null on Windows */
|
#endif /* _WIN32 There is no /dev/null on Windows */
|
||||||
|
|
||||||
int torture_run_tests(void) {
|
int torture_run_tests(void) {
|
||||||
@@ -738,6 +814,9 @@ int torture_run_tests(void) {
|
|||||||
cmocka_unit_test_setup_teardown(torture_knownhosts_algorithms_global,
|
cmocka_unit_test_setup_teardown(torture_knownhosts_algorithms_global,
|
||||||
setup_knownhosts_file,
|
setup_knownhosts_file,
|
||||||
teardown_knownhosts_file),
|
teardown_knownhosts_file),
|
||||||
|
cmocka_unit_test_setup_teardown(torture_knownhosts_has_entry,
|
||||||
|
setup_bad_knownhosts_file,
|
||||||
|
teardown_knownhosts_file),
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user