kex: Use ssh_known_hosts_get_algorithms()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Этот коммит содержится в:
родитель
83a46c7756
Коммит
539d7ba249
89
src/kex.c
89
src/kex.c
@ -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),
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user