1
1

kex: Use ssh_known_hosts_get_algorithms()

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Этот коммит содержится в:
Andreas Schneider 2018-07-03 08:19:14 +02:00
родитель 83a46c7756
Коммит 539d7ba249
2 изменённых файлов: 64 добавлений и 62 удалений

Просмотреть файл

@ -36,6 +36,7 @@
#include "libssh/string.h"
#include "libssh/curve25519.h"
#include "libssh/knownhosts.h"
#include "libssh/misc.h"
#ifdef HAVE_LIBGCRYPT
# define BLOWFISH "blowfish-cbc,"
@ -564,7 +565,8 @@ void ssh_list_kex(struct ssh_kex_struct *kex) {
* @returns a cstring containing a comma-separated list of hostkey methods.
* NULL if no method matches
*/
static char *ssh_client_select_hostkeys(ssh_session session){
static char *ssh_client_select_hostkeys(ssh_session session)
{
char methods_buffer[128]={0};
static const char *preferred_hostkeys[] = {
"ssh-ed25519",
@ -577,42 +579,65 @@ static char *ssh_client_select_hostkeys(ssh_session session){
#endif
NULL
};
char **methods;
int i,j;
int needcoma=0;
struct ssh_list *algo_list = NULL;
struct ssh_iterator *it = NULL;
size_t algo_count;
int needcomma = 0;
int i;
methods = ssh_knownhosts_algorithms(session);
if (methods == NULL || methods[0] == NULL){
SAFE_FREE(methods);
return NULL;
}
algo_list = ssh_known_hosts_get_algorithms(session);
if (algo_list == NULL) {
return NULL;
}
for (i=0;preferred_hostkeys[i] != NULL; ++i){
for (j=0; methods[j] != NULL; ++j){
if(strcmp(preferred_hostkeys[i], methods[j]) == 0){
if (ssh_verify_existing_algo(SSH_HOSTKEYS, methods[j])){
if(needcoma)
strncat(methods_buffer,",",sizeof(methods_buffer)-strlen(methods_buffer)-1);
strncat(methods_buffer, methods[j], sizeof(methods_buffer)-strlen(methods_buffer)-1);
needcoma = 1;
}
}
}
}
for(i=0;methods[i]!= NULL; ++i){
SAFE_FREE(methods[i]);
}
SAFE_FREE(methods);
algo_count = ssh_list_count(algo_list);
if (algo_count == 0) {
ssh_list_free(algo_list);
return NULL;
}
if(strlen(methods_buffer) > 0){
SSH_LOG(SSH_LOG_DEBUG, "Changing host key method to \"%s\"", methods_buffer);
return strdup(methods_buffer);
} else {
SSH_LOG(SSH_LOG_DEBUG, "No supported kex method for existing key in known_hosts file");
return NULL;
}
for (i = 0; preferred_hostkeys[i] != NULL; ++i) {
for (it = ssh_list_get_iterator(algo_list);
it != NULL;
it = ssh_list_get_iterator(algo_list)) {
const char *algo = ssh_iterator_value(const char *, it);
int cmp;
int ok;
cmp = strcmp(preferred_hostkeys[i], algo);
if (cmp == 0) {
ok = ssh_verify_existing_algo(SSH_HOSTKEYS, algo);
if (ok) {
if (needcomma) {
strncat(methods_buffer,
",",
sizeof(methods_buffer) - strlen(methods_buffer) - 1);
}
strncat(methods_buffer,
algo,
sizeof(methods_buffer) - strlen(methods_buffer) - 1);
needcomma = 1;
}
}
ssh_list_remove(algo_list, it);
}
}
ssh_list_free(algo_list);
if (strlen(methods_buffer) == 0) {
SSH_LOG(SSH_LOG_DEBUG,
"No supported kex method for existing key in known_hosts file");
return NULL;
}
SSH_LOG(SSH_LOG_DEBUG,
"Changing host key method to \"%s\"",
methods_buffer);
return strdup(methods_buffer);
}
/**
* @brief sets the key exchange parameters to be sent to the server,
* in function of the options and available methods.

Просмотреть файл

@ -40,18 +40,7 @@
"YgIytryNn7LLiwYfoSxvWigFrTTZsrVtCOYyNgklmffpGdzuC43wdANvTewfI9G" \
"o71r8EXmEc228CrYPmb8Scv3mpXFK/BosohSGkPlEHu9lf3YjnknBicDaVtJOYp" \
"wnXJPjZo2EhG79HxDRpjJHH"
#ifdef HAVE_DSA
#define BADDSA "AAAAB3NzaC1kc3MAAACBAITDKqGQ5aC5wHySG6ZdL1+BVBY2nLP5vzw3i3pvZfP" \
"yNUS0UCwrt5pajsMvDRGXXebTJhWVonDnv8tpSgiuIBXMZrma8CU1KCFGRzwb/n8" \
"cc5tJmIphlOUTrObjBmsRz7u1eZmoaddXC9ask6BNnt0DmhzYi2esL3mbardy8IN" \
"zAAAAFQDlPFCm410pgQQPb3X5FWjyVEIl+QAAAIAp0vqfir8K8p+zP4dzFG7ppnt" \
"DjaXf3ge6URF7f5xPDo6CClGo2JQ2REF8NxM7K9cLgR9Ifx2ahO48UMgrXEl/BOp" \
"IQHpeBqUz26a49O5J0WEW16YSUHxWwMxWVe/SRmyKdTUZJ6fcepH88JNqm3XudNn" \
"s78grM+yx9mcXnK2AsAAAAIBxpF8ZQIlGrSgwCmCfwjP156bC3Ya6LYf9ZpLJ0dX" \
"EcxqLVllrNEvd2EGD9p16BYO2yaalYon8im59PtOcul2ay5XQ6rVDQ2T0pgNUpsI" \
"h0dSi8VJXI1wes5HTyLsv9VBmU1uCXUUvufoQKfF/OcSH0ufcCpnd62g1/adZcy2" \
"WJg=="
#endif
#define BADED25519 "AAAAC3NzaC1lZDI1NTE5AAAAIE74wHmKKkrxpW/dZ69pKPlMoWG9VvWfrNnUkWRQqaDa"
static int sshd_setup(void **state)
{
@ -189,7 +178,6 @@ static void torture_knownhosts_fail(void **state) {
assert_int_equal(rc, SSH_SERVER_KNOWN_CHANGED);
}
#ifdef HAVE_DSA
static void torture_knownhosts_other(void **state) {
struct torture_state *s = *state;
ssh_session session = s->ssh.session;
@ -206,7 +194,7 @@ static void torture_knownhosts_other(void **state) {
rc = ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, known_hosts_file);
assert_int_equal(rc, SSH_OK);
rc = ssh_options_set(session, SSH_OPTIONS_HOSTKEYS, "ssh-dss");
rc = ssh_options_set(session, SSH_OPTIONS_HOSTKEYS, "ssh-ed25519");
assert_int_equal(rc, SSH_OK);
file = fopen(known_hosts_file, "w");
@ -239,7 +227,7 @@ static void torture_knownhosts_other_auto(void **state) {
rc = ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, known_hosts_file);
assert_int_equal(rc, SSH_OK);
rc = ssh_options_set(session, SSH_OPTIONS_HOSTKEYS, "ssh-dss");
rc = ssh_options_set(session, SSH_OPTIONS_HOSTKEYS, "ssh-ed25519");
assert_int_equal(rc, SSH_OK);
rc = ssh_connect(session);
@ -269,13 +257,12 @@ static void torture_knownhosts_other_auto(void **state) {
rc = ssh_connect(session);
assert_true(rc==SSH_OK);
/* ssh-rsa is the default but libssh should try ssh-dss instead */
/* ssh-rsa is the default but libssh should try ssh-ed25519 instead */
rc = ssh_is_server_known(session);
assert_int_equal(rc, SSH_SERVER_KNOWN_OK);
/* session will be freed by session_teardown() */
}
#endif
static void torture_knownhosts_conflict(void **state) {
struct torture_state *s = *state;
@ -302,9 +289,7 @@ static void torture_knownhosts_conflict(void **state) {
file = fopen(known_hosts_file, "w");
assert_true(file != NULL);
fprintf(file, "127.0.0.10 ssh-rsa %s\n", BADRSA);
#ifdef HAVE_DSA
fprintf(file, "127.0.0.10 ssh-dss %s\n", BADDSA);
#endif
fprintf(file, "127.0.0.10 ssh-ed25519 %s\n", BADED25519);
fclose(file);
rc = ssh_connect(session);
@ -362,21 +347,15 @@ static void torture_knownhosts_precheck(void **state) {
file = fopen(known_hosts_file, "w");
assert_true(file != NULL);
fprintf(file, "127.0.0.10 ssh-rsa %s\n", BADRSA);
#ifdef HAVE_DSA
fprintf(file, "127.0.0.10 ssh-dss %s\n", BADDSA);
#endif
fprintf(file, "127.0.0.10 ssh-ed25519 %s\n", BADED25519);
fclose(file);
kex = ssh_knownhosts_algorithms(session);
assert_true(kex != NULL);
assert_string_equal(kex[0],"ssh-rsa");
#ifdef HAVE_DSA
assert_string_equal(kex[1],"ssh-dss");
assert_string_equal(kex[1],"ssh-ed25519");
assert_true(kex[2]==NULL);
free(kex[1]);
#else
assert_true(kex[1]==NULL);
#endif
free(kex[0]);
free(kex);
}
@ -390,14 +369,12 @@ int torture_run_tests(void) {
cmocka_unit_test_setup_teardown(torture_knownhosts_fail,
session_setup,
session_teardown),
#ifdef HAVE_DSA
cmocka_unit_test_setup_teardown(torture_knownhosts_other,
session_setup,
session_teardown),
cmocka_unit_test_setup_teardown(torture_knownhosts_other_auto,
session_setup,
session_teardown),
#endif
cmocka_unit_test_setup_teardown(torture_knownhosts_conflict,
session_setup,
session_teardown),