mirror of
https://git.libssh.org/projects/libssh.git
synced 2026-02-04 12:20:42 +09:00
Compare commits
17 Commits
301d0e16df
...
39a62cef44
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
39a62cef44 | ||
|
|
7969b6de3c | ||
|
|
b207e39d28 | ||
|
|
6230b24ff5 | ||
|
|
e668b03dd7 | ||
|
|
77ce02d809 | ||
|
|
d61b0dc7cc | ||
|
|
d12eb770ac | ||
|
|
03b29a6874 | ||
|
|
99957fb561 | ||
|
|
3e9175e66a | ||
|
|
bf295abb5b | ||
|
|
7f14df3eac | ||
|
|
c206e5d84e | ||
|
|
274b8f19b3 | ||
|
|
39a88d62c9 | ||
|
|
94f12090b5 |
28
src/bind.c
28
src/bind.c
@@ -218,28 +218,12 @@ static int ssh_bind_import_keys(ssh_bind sshbind) {
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
int ssh_bind_listen(ssh_bind sshbind) {
|
||||
int ssh_bind_listen(ssh_bind sshbind)
|
||||
{
|
||||
const char *host = NULL;
|
||||
socket_t fd;
|
||||
int rc;
|
||||
|
||||
/* Apply global bind configurations, if it hasn't been applied before */
|
||||
rc = ssh_bind_options_parse_config(sshbind, NULL);
|
||||
if (rc != 0) {
|
||||
ssh_set_error(sshbind, SSH_FATAL,"Could not parse global config");
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
/* Set default hostkey paths if no hostkey was found before */
|
||||
if (sshbind->ecdsakey == NULL &&
|
||||
sshbind->rsakey == NULL &&
|
||||
sshbind->ed25519key == NULL) {
|
||||
|
||||
sshbind->ecdsakey = strdup("/etc/ssh/ssh_host_ecdsa_key");
|
||||
sshbind->rsakey = strdup("/etc/ssh/ssh_host_rsa_key");
|
||||
sshbind->ed25519key = strdup("/etc/ssh/ssh_host_ed25519_key");
|
||||
}
|
||||
|
||||
/* Apply global bind configurations, if it hasn't been applied before */
|
||||
rc = ssh_bind_options_parse_config(sshbind, NULL);
|
||||
if (rc != 0) {
|
||||
@@ -289,10 +273,10 @@ int ssh_bind_listen(ssh_bind sshbind) {
|
||||
}
|
||||
|
||||
sshbind->bindfd = fd;
|
||||
} else {
|
||||
SSH_LOG(SSH_LOG_DEBUG, "Using app-provided bind socket");
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
SSH_LOG(SSH_LOG_DEBUG, "Using app-provided bind socket");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ssh_bind_set_callbacks(ssh_bind sshbind, ssh_bind_callbacks callbacks, void *userdata)
|
||||
|
||||
@@ -836,6 +836,7 @@ error:
|
||||
session->opts.fd = SSH_INVALID_SOCKET;
|
||||
session->session_state = SSH_SESSION_STATE_DISCONNECTED;
|
||||
session->pending_call_state = SSH_PENDING_CALL_NONE;
|
||||
session->packet_state = PACKET_STATE_INIT;
|
||||
|
||||
while ((it = ssh_list_get_iterator(session->channels)) != NULL) {
|
||||
ssh_channel_do_free(ssh_iterator_value(ssh_channel, it));
|
||||
|
||||
10
src/config.c
10
src/config.c
@@ -1066,13 +1066,11 @@ ssh_config_parse_line(ssh_session session,
|
||||
}
|
||||
break;
|
||||
case SOC_USERNAME:
|
||||
if (session->opts.username == NULL) {
|
||||
p = ssh_config_get_str_tok(&s, NULL);
|
||||
if (p && *parsing) {
|
||||
p = ssh_config_get_str_tok(&s, NULL);
|
||||
if (p && *parsing) {
|
||||
ssh_options_set(session, SSH_OPTIONS_USER, p);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SOC_IDENTITY:
|
||||
p = ssh_config_get_str_tok(&s, NULL);
|
||||
if (p && *parsing) {
|
||||
|
||||
@@ -166,7 +166,7 @@ int ssh_connector_set_out_channel(ssh_connector connector,
|
||||
|
||||
/* Fallback to default value for invalid flags */
|
||||
if (!(flags & SSH_CONNECTOR_STDOUT) && !(flags & SSH_CONNECTOR_STDERR)) {
|
||||
connector->in_flags = SSH_CONNECTOR_STDOUT;
|
||||
connector->out_flags = SSH_CONNECTOR_STDOUT;
|
||||
}
|
||||
|
||||
return ssh_add_channel_callbacks(channel, &connector->out_channel_cb);
|
||||
@@ -381,15 +381,13 @@ ssh_connector_fd_out_cb(ssh_connector connector)
|
||||
*
|
||||
* @returns 0
|
||||
*/
|
||||
static int ssh_connector_fd_cb(ssh_poll_handle p,
|
||||
static int ssh_connector_fd_cb(UNUSED_PARAM(ssh_poll_handle p),
|
||||
socket_t fd,
|
||||
int revents,
|
||||
void *userdata)
|
||||
{
|
||||
ssh_connector connector = userdata;
|
||||
|
||||
(void)p;
|
||||
|
||||
if (revents & POLLERR) {
|
||||
ssh_connector_except(connector, fd);
|
||||
} else if((revents & (POLLIN|POLLHUP)) && fd == connector->in_fd) {
|
||||
@@ -419,7 +417,7 @@ static int ssh_connector_fd_cb(ssh_poll_handle p,
|
||||
* @returns Amount of data bytes consumed
|
||||
*/
|
||||
static int ssh_connector_channel_data_cb(ssh_session session,
|
||||
ssh_channel channel,
|
||||
UNUSED_PARAM(ssh_channel channel),
|
||||
void *data,
|
||||
uint32_t len,
|
||||
int is_stderr,
|
||||
@@ -429,10 +427,6 @@ static int ssh_connector_channel_data_cb(ssh_session session,
|
||||
int w;
|
||||
uint32_t window;
|
||||
|
||||
(void) session;
|
||||
(void) channel;
|
||||
(void) is_stderr;
|
||||
|
||||
SSH_LOG(SSH_LOG_TRACE,"connector data on channel");
|
||||
|
||||
if (is_stderr && !(connector->in_flags & SSH_CONNECTOR_STDERR)) {
|
||||
@@ -510,10 +504,11 @@ static int ssh_connector_channel_data_cb(ssh_session session,
|
||||
*
|
||||
* @returns Amount of data bytes consumed
|
||||
*/
|
||||
static int ssh_connector_channel_write_wontblock_cb(ssh_session session,
|
||||
ssh_channel channel,
|
||||
uint32_t bytes,
|
||||
void *userdata)
|
||||
static int
|
||||
ssh_connector_channel_write_wontblock_cb(ssh_session session,
|
||||
UNUSED_PARAM(ssh_channel channel),
|
||||
uint32_t bytes,
|
||||
void *userdata)
|
||||
{
|
||||
ssh_connector connector = userdata;
|
||||
uint8_t buffer[CHUNKSIZE];
|
||||
|
||||
@@ -376,25 +376,23 @@ struct ssh_list *ssh_known_hosts_get_algorithms(ssh_session session)
|
||||
}
|
||||
}
|
||||
|
||||
host_port = ssh_session_get_host_port(session);
|
||||
if (host_port == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
list = ssh_list_new();
|
||||
if (list == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
SAFE_FREE(host_port);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
host_port = ssh_session_get_host_port(session);
|
||||
if (host_port == NULL) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = ssh_known_hosts_read_entries(host_port,
|
||||
session->opts.knownhosts,
|
||||
&entry_list);
|
||||
if (rc != 0) {
|
||||
ssh_list_free(entry_list);
|
||||
ssh_list_free(list);
|
||||
return NULL;
|
||||
SAFE_FREE(host_port);
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = ssh_known_hosts_read_entries(host_port,
|
||||
@@ -402,21 +400,16 @@ struct ssh_list *ssh_known_hosts_get_algorithms(ssh_session session)
|
||||
&entry_list);
|
||||
SAFE_FREE(host_port);
|
||||
if (rc != 0) {
|
||||
ssh_list_free(entry_list);
|
||||
ssh_list_free(list);
|
||||
return NULL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (entry_list == NULL) {
|
||||
ssh_list_free(list);
|
||||
return NULL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
count = ssh_list_count(entry_list);
|
||||
if (count == 0) {
|
||||
ssh_list_free(list);
|
||||
ssh_list_free(entry_list);
|
||||
return NULL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
for (it = ssh_list_get_iterator(entry_list);
|
||||
@@ -460,6 +453,7 @@ struct ssh_list *ssh_known_hosts_get_algorithms(ssh_session session)
|
||||
|
||||
return list;
|
||||
error:
|
||||
ssh_list_free(entry_list);
|
||||
ssh_list_free(list);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -701,8 +701,8 @@ int ssh_key_cmp(const ssh_key k1,
|
||||
ssh_buffer_get_len(k1->cert));
|
||||
}
|
||||
|
||||
if (k1->type == SSH_KEYTYPE_ED25519 ||
|
||||
k1->type == SSH_KEYTYPE_SK_ED25519) {
|
||||
if (ssh_key_type_plain(k1->type) == SSH_KEYTYPE_ED25519 ||
|
||||
ssh_key_type_plain(k1->type) == SSH_KEYTYPE_SK_ED25519) {
|
||||
return pki_ed25519_key_cmp(k1, k2, what);
|
||||
}
|
||||
|
||||
|
||||
@@ -1355,7 +1355,7 @@ int pki_key_compare(const ssh_key k1,
|
||||
case SSH_KEYTYPE_SK_ED25519:
|
||||
case SSH_KEYTYPE_SK_ED25519_CERT01:
|
||||
/* ed25519 keys handled globally */
|
||||
return 0;
|
||||
return 1;
|
||||
case SSH_KEYTYPE_ECDSA_P256:
|
||||
case SSH_KEYTYPE_ECDSA_P256_CERT01:
|
||||
case SSH_KEYTYPE_ECDSA_P384:
|
||||
|
||||
@@ -782,7 +782,7 @@ int pki_key_compare(const ssh_key k1, const ssh_key k2, enum ssh_keycmp_e what)
|
||||
case SSH_KEYTYPE_ED25519:
|
||||
case SSH_KEYTYPE_SK_ED25519:
|
||||
/* ed25519 keys handled globally */
|
||||
rc = 0;
|
||||
rc = 1;
|
||||
break;
|
||||
default:
|
||||
rc = 1;
|
||||
|
||||
@@ -495,6 +495,11 @@ static size_t callback_receive_banner(const void *data, size_t len, void *user)
|
||||
buffer[i] = '\0';
|
||||
|
||||
str = strdup(buffer);
|
||||
if (str == NULL) {
|
||||
session->session_state = SSH_SESSION_STATE_ERROR;
|
||||
ssh_set_error_oom(session);
|
||||
return 0;
|
||||
}
|
||||
/* number of bytes read */
|
||||
processed = i + 1;
|
||||
session->clientbanner = str;
|
||||
|
||||
@@ -373,10 +373,10 @@ if (FUZZ_TESTING)
|
||||
endif()
|
||||
|
||||
add_custom_target(test_memcheck
|
||||
# FIXME: The threads_pki_rsa test is skipped under valgrind as it times out
|
||||
# FIXME: The pkd_hello_i1 test is skipped under valgrind as it times out
|
||||
# Passing suppression file is also stupid so lets go with override here:
|
||||
# https://stackoverflow.com/a/56116311
|
||||
COMMAND ${CMAKE_CTEST_COMMAND} -E torture_threads_pki_rsa -E pkd_hello_i1
|
||||
COMMAND ${CMAKE_CTEST_COMMAND} -E pkd_hello_i1
|
||||
--output-on-failure --force-new-ctest-process --test-action memcheck
|
||||
--overwrite MemoryCheckSuppressionFile=${CMAKE_SOURCE_DIR}/tests/valgrind.supp
|
||||
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}")
|
||||
|
||||
@@ -53,6 +53,8 @@ extern LIBSSH_THREAD int ssh_log_level;
|
||||
#define LIBSSH_TEST_NONEWLINEONELINE "libssh_test_NoNewLineOneline.tmp"
|
||||
#define LIBSSH_TEST_RECURSIVE_INCLUDE "libssh_test_recursive_include.tmp"
|
||||
#define LIBSSH_TESTCONFIG_MATCH_COMPLEX "libssh_test_match_complex.tmp"
|
||||
#define LIBSSH_TESTCONFIG_LOGLEVEL_MISSING "libssh_test_loglevel_missing.tmp"
|
||||
#define LIBSSH_TESTCONFIG_JUMP "libssh_test_jump.tmp"
|
||||
|
||||
#define LIBSSH_TESTCONFIG_STRING1 \
|
||||
"User "USERNAME"\nInclude "LIBSSH_TESTCONFIG2"\n\n"
|
||||
@@ -243,6 +245,26 @@ extern LIBSSH_THREAD int ssh_log_level;
|
||||
"\tForwardAgent yes\n" \
|
||||
"\tHostName complex-match\n"
|
||||
|
||||
#define LIBSSH_TESTCONFIG_LOGLEVEL_MISSING_STRING "LogLevel\n"
|
||||
#define LIBSSH_TESTCONFIG_JUMP_STRING \
|
||||
"# The jump host\n" \
|
||||
"Host ub-jumphost\n" \
|
||||
" HostName 1xxxxxx\n" \
|
||||
" User ubuntu\n" \
|
||||
" IdentityFile ~/of/temp-libssh.pem\n" \
|
||||
" Port 23\n" \
|
||||
" LogLevel DEBUG3\n" \
|
||||
"\n" \
|
||||
"# Cisco Router through Jump Host\n" \
|
||||
"Host cisco-router\n" \
|
||||
" HostName xx.xxxxxxxxx\n" \
|
||||
" User username\n" \
|
||||
" ProxyJump ub-jumphost\n" \
|
||||
" Port 5555\n" \
|
||||
" #RequiredRSASize 512\n" \
|
||||
" PasswordAuthentication yes\n" \
|
||||
" LogLevel DEBUG3\n"
|
||||
|
||||
/**
|
||||
* @brief helper function loading configuration from either file or string
|
||||
*/
|
||||
@@ -293,6 +315,8 @@ static int setup_config_files(void **state)
|
||||
unlink(LIBSSH_TEST_NONEWLINEEND);
|
||||
unlink(LIBSSH_TEST_NONEWLINEONELINE);
|
||||
unlink(LIBSSH_TESTCONFIG_MATCH_COMPLEX);
|
||||
unlink(LIBSSH_TESTCONFIG_LOGLEVEL_MISSING);
|
||||
unlink(LIBSSH_TESTCONFIG_JUMP);
|
||||
|
||||
torture_write_file(LIBSSH_TESTCONFIG1,
|
||||
LIBSSH_TESTCONFIG_STRING1);
|
||||
@@ -361,6 +385,10 @@ static int setup_config_files(void **state)
|
||||
/* Match complex combinations */
|
||||
torture_write_file(LIBSSH_TESTCONFIG_MATCH_COMPLEX,
|
||||
LIBSSH_TESTCONFIG_MATCH_COMPLEX_STRING);
|
||||
torture_write_file(LIBSSH_TESTCONFIG_LOGLEVEL_MISSING,
|
||||
LIBSSH_TESTCONFIG_LOGLEVEL_MISSING_STRING);
|
||||
torture_write_file(LIBSSH_TESTCONFIG_JUMP,
|
||||
LIBSSH_TESTCONFIG_JUMP_STRING);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -390,6 +418,8 @@ static int teardown_config_files(void **state)
|
||||
unlink(LIBSSH_TEST_NONEWLINEEND);
|
||||
unlink(LIBSSH_TEST_NONEWLINEONELINE);
|
||||
unlink(LIBSSH_TESTCONFIG_MATCH_COMPLEX);
|
||||
unlink(LIBSSH_TESTCONFIG_LOGLEVEL_MISSING);
|
||||
unlink(LIBSSH_TESTCONFIG_JUMP);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -2617,6 +2647,112 @@ static void torture_config_match_complex(void **state)
|
||||
ssh_string_free_char(v);
|
||||
}
|
||||
|
||||
/* Missing value to LogLevel configuration option
|
||||
*/
|
||||
static void torture_config_loglevel_missing_value(void **state)
|
||||
{
|
||||
ssh_session session = *state;
|
||||
|
||||
ssh_options_set(session, SSH_OPTIONS_HOST, "Bar");
|
||||
|
||||
_parse_config(session, LIBSSH_TESTCONFIG_LOGLEVEL_MISSING, NULL, SSH_OK);
|
||||
}
|
||||
|
||||
static int before_connection(ssh_session jump_session, void *user)
|
||||
{
|
||||
char *v = NULL;
|
||||
int ret;
|
||||
|
||||
(void)user;
|
||||
|
||||
/* During the connection, we force parsing the same configuration file
|
||||
* (would be normally parsed automatically during the connection itself)
|
||||
*/
|
||||
ret = ssh_config_parse_file(jump_session, LIBSSH_TESTCONFIG_JUMP);
|
||||
assert_return_code(ret, errno);
|
||||
|
||||
/* Test the variable presence */
|
||||
ret = ssh_options_get(jump_session, SSH_OPTIONS_HOST, &v);
|
||||
assert_return_code(ret, errno);
|
||||
assert_string_equal(v, "1xxxxxx");
|
||||
ssh_string_free_char(v);
|
||||
|
||||
ret = ssh_options_get(jump_session, SSH_OPTIONS_USER, &v);
|
||||
assert_return_code(ret, errno);
|
||||
assert_string_equal(v, "ubuntu");
|
||||
ssh_string_free_char(v);
|
||||
|
||||
assert_int_equal(jump_session->opts.port, 23);
|
||||
|
||||
/* Fail the connection -- we are in unit tests so it would fail anyway */
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int verify_knownhost(ssh_session jump_session, void *user)
|
||||
{
|
||||
(void)jump_session;
|
||||
(void)user;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int authenticate(ssh_session jump_session, void *user)
|
||||
{
|
||||
(void)jump_session;
|
||||
(void)user;
|
||||
|
||||
return 0;
|
||||
}
|
||||
/* Reproducer for complex proxy jump
|
||||
*/
|
||||
static void torture_config_jump(void **state)
|
||||
{
|
||||
ssh_session session = *state;
|
||||
struct ssh_jump_callbacks_struct c = {
|
||||
.before_connection = before_connection,
|
||||
.verify_knownhost = verify_knownhost,
|
||||
.authenticate = authenticate,
|
||||
};
|
||||
char *v = NULL;
|
||||
int ret;
|
||||
|
||||
ssh_options_set(session, SSH_OPTIONS_HOST, "cisco-router");
|
||||
|
||||
_parse_config(session, LIBSSH_TESTCONFIG_JUMP, NULL, SSH_OK);
|
||||
|
||||
/* Test the variable presence */
|
||||
ret = ssh_options_get(session, SSH_OPTIONS_HOST, &v);
|
||||
assert_return_code(ret, errno);
|
||||
assert_string_equal(v, "xx.xxxxxxxxx");
|
||||
ssh_string_free_char(v);
|
||||
|
||||
ret = ssh_options_get(session, SSH_OPTIONS_USER, &v);
|
||||
assert_return_code(ret, errno);
|
||||
assert_string_equal(v, "username");
|
||||
ssh_string_free_char(v);
|
||||
|
||||
assert_int_equal(session->opts.port, 5555);
|
||||
|
||||
/* At this point, the configuration file is not parsed for the jump host so
|
||||
* we are getting just the the hostname -- the port and username will get
|
||||
* pulled during the session connecting to this host */
|
||||
assert_int_equal(ssh_list_count(session->opts.proxy_jumps), 1);
|
||||
helper_proxy_jump_check(session->opts.proxy_jumps->root,
|
||||
"ub-jumphost",
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
/* Set up the callbacks -- they should verify we are going to connect to the
|
||||
* right host */
|
||||
ret = ssh_options_set(session, SSH_OPTIONS_PROXYJUMP_CB_LIST_APPEND, &c);
|
||||
assert_ssh_return_code(session, ret);
|
||||
|
||||
ret = ssh_connect(session);
|
||||
assert_ssh_return_code_equal(session, ret, SSH_ERROR);
|
||||
|
||||
printf("%s: EOF\n", __func__);
|
||||
}
|
||||
|
||||
int torture_run_tests(void)
|
||||
{
|
||||
int rc;
|
||||
@@ -2713,6 +2849,12 @@ int torture_run_tests(void)
|
||||
setup, teardown),
|
||||
cmocka_unit_test_setup_teardown(torture_config_match_complex,
|
||||
setup, teardown),
|
||||
cmocka_unit_test_setup_teardown(torture_config_loglevel_missing_value,
|
||||
setup,
|
||||
teardown),
|
||||
cmocka_unit_test_setup_teardown(torture_config_jump,
|
||||
setup,
|
||||
teardown),
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -367,10 +367,14 @@ static void torture_pki_ecdsa_publickey_from_privatekey(void **state)
|
||||
static void torture_pki_ecdsa_import_cert_file(void **state)
|
||||
{
|
||||
int rc;
|
||||
ssh_key pubkey = NULL;
|
||||
ssh_key privkey = NULL;
|
||||
ssh_key cert = NULL;
|
||||
enum ssh_keytypes_e type;
|
||||
enum ssh_keytypes_e type, exp_cert_type;
|
||||
struct pki_st *test_state = *((struct pki_st **)state);
|
||||
|
||||
exp_cert_type = test_state->type + 3;
|
||||
|
||||
/* Importing public key as cert should fail */
|
||||
rc = ssh_pki_import_cert_file(LIBSSH_ECDSA_TESTKEY ".pub", &cert);
|
||||
assert_int_equal(rc, SSH_ERROR);
|
||||
@@ -380,13 +384,78 @@ static void torture_pki_ecdsa_import_cert_file(void **state)
|
||||
assert_int_equal(rc, 0);
|
||||
assert_non_null(cert);
|
||||
|
||||
rc = ssh_pki_import_pubkey_file(LIBSSH_ECDSA_TESTKEY ".pub", &pubkey);
|
||||
assert_return_code(rc, errno);
|
||||
assert_non_null(pubkey);
|
||||
|
||||
type = ssh_key_type(cert);
|
||||
assert_int_equal(type, test_state->type+3);
|
||||
assert_int_equal(type, exp_cert_type);
|
||||
|
||||
rc = ssh_key_is_public(cert);
|
||||
assert_int_equal(rc, 1);
|
||||
|
||||
/* Import matching private key file and verify the pubkey matches */
|
||||
rc = ssh_pki_import_privkey_file(LIBSSH_ECDSA_TESTKEY,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&privkey);
|
||||
assert_return_code(rc, errno);
|
||||
assert_non_null(privkey);
|
||||
|
||||
type = ssh_key_type(privkey);
|
||||
assert_true(type == test_state->type);
|
||||
|
||||
/* Basic sanity. */
|
||||
rc = ssh_pki_copy_cert_to_privkey(NULL, privkey);
|
||||
assert_int_equal(rc, SSH_ERROR);
|
||||
|
||||
rc = ssh_pki_copy_cert_to_privkey(pubkey, NULL);
|
||||
assert_int_equal(rc, SSH_ERROR);
|
||||
|
||||
/* A public key doesn't have a cert, copy should fail. */
|
||||
assert_null(pubkey->cert);
|
||||
rc = ssh_pki_copy_cert_to_privkey(pubkey, privkey);
|
||||
assert_int_equal(rc, SSH_ERROR);
|
||||
|
||||
/* Copying the cert to non-cert keys should work fine. */
|
||||
rc = ssh_pki_copy_cert_to_privkey(cert, pubkey);
|
||||
assert_return_code(rc, errno);
|
||||
assert_non_null(pubkey->cert);
|
||||
rc = ssh_pki_copy_cert_to_privkey(cert, privkey);
|
||||
assert_return_code(rc, errno);
|
||||
assert_non_null(privkey->cert);
|
||||
assert_true(privkey->cert_type == exp_cert_type);
|
||||
|
||||
assert_int_equal(ssh_key_cmp(privkey, cert, SSH_KEY_CMP_PUBLIC), 0);
|
||||
assert_int_equal(ssh_key_cmp(cert, privkey, SSH_KEY_CMP_PUBLIC), 0);
|
||||
|
||||
/* The private key's cert is already set, another copy should fail. */
|
||||
rc = ssh_pki_copy_cert_to_privkey(cert, privkey);
|
||||
assert_int_equal(rc, SSH_ERROR);
|
||||
|
||||
SSH_KEY_FREE(privkey);
|
||||
SSH_KEY_FREE(pubkey);
|
||||
|
||||
/* Generate different key and try to assign it this certificate */
|
||||
rc = ssh_pki_generate(test_state->type, 256, &privkey);
|
||||
assert_return_code(rc, errno);
|
||||
assert_non_null(privkey);
|
||||
rc = ssh_pki_export_privkey_to_pubkey(privkey, &pubkey);
|
||||
assert_return_code(rc, errno);
|
||||
assert_non_null(pubkey);
|
||||
|
||||
rc = ssh_pki_copy_cert_to_privkey(cert, privkey);
|
||||
assert_int_equal(rc, SSH_ERROR);
|
||||
rc = ssh_pki_copy_cert_to_privkey(cert, pubkey);
|
||||
assert_int_equal(rc, SSH_ERROR);
|
||||
|
||||
assert_int_equal(ssh_key_cmp(privkey, cert, SSH_KEY_CMP_PUBLIC), 1);
|
||||
assert_int_equal(ssh_key_cmp(cert, privkey, SSH_KEY_CMP_PUBLIC), 1);
|
||||
|
||||
SSH_KEY_FREE(cert);
|
||||
SSH_KEY_FREE(privkey);
|
||||
SSH_KEY_FREE(pubkey);
|
||||
}
|
||||
|
||||
static void torture_pki_ecdsa_publickey_base64(void **state)
|
||||
|
||||
@@ -312,6 +312,8 @@ static void torture_pki_ed25519_publickey_from_privatekey(void **state)
|
||||
static void torture_pki_ed25519_import_cert_file(void **state)
|
||||
{
|
||||
int rc;
|
||||
ssh_key pubkey = NULL;
|
||||
ssh_key privkey = NULL;
|
||||
ssh_key cert = NULL;
|
||||
enum ssh_keytypes_e type;
|
||||
|
||||
@@ -323,16 +325,88 @@ static void torture_pki_ed25519_import_cert_file(void **state)
|
||||
assert_null(cert);
|
||||
|
||||
rc = ssh_pki_import_cert_file(LIBSSH_ED25519_TESTKEY "-cert.pub", &cert);
|
||||
assert_true(rc == 0);
|
||||
assert_return_code(rc, errno);
|
||||
assert_non_null(cert);
|
||||
|
||||
rc = ssh_pki_import_pubkey_file(LIBSSH_ED25519_TESTKEY ".pub", &pubkey);
|
||||
assert_return_code(rc, errno);
|
||||
assert_non_null(pubkey);
|
||||
|
||||
type = ssh_key_type(cert);
|
||||
assert_true(type == SSH_KEYTYPE_ED25519_CERT01);
|
||||
|
||||
rc = ssh_key_is_public(cert);
|
||||
assert_true(rc == 1);
|
||||
assert_int_equal(rc, 1);
|
||||
|
||||
/* Skip test if in FIPS mode */
|
||||
if (ssh_fips_mode()) {
|
||||
SSH_KEY_FREE(cert);
|
||||
SSH_KEY_FREE(pubkey);
|
||||
skip();
|
||||
}
|
||||
|
||||
/* Import matching private key file and verify the pubkey matches */
|
||||
rc = ssh_pki_import_privkey_file(LIBSSH_ED25519_TESTKEY,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&privkey);
|
||||
assert_return_code(rc, errno);
|
||||
assert_non_null(privkey);
|
||||
|
||||
type = ssh_key_type(privkey);
|
||||
assert_true(type == SSH_KEYTYPE_ED25519);
|
||||
|
||||
/* Basic sanity. */
|
||||
rc = ssh_pki_copy_cert_to_privkey(NULL, privkey);
|
||||
assert_int_equal(rc, SSH_ERROR);
|
||||
|
||||
rc = ssh_pki_copy_cert_to_privkey(pubkey, NULL);
|
||||
assert_int_equal(rc, SSH_ERROR);
|
||||
|
||||
/* A public key doesn't have a cert, copy should fail. */
|
||||
assert_null(pubkey->cert);
|
||||
rc = ssh_pki_copy_cert_to_privkey(pubkey, privkey);
|
||||
assert_int_equal(rc, SSH_ERROR);
|
||||
|
||||
/* Copying the cert to non-cert keys should work fine. */
|
||||
rc = ssh_pki_copy_cert_to_privkey(cert, pubkey);
|
||||
assert_return_code(rc, errno);
|
||||
assert_non_null(pubkey->cert);
|
||||
rc = ssh_pki_copy_cert_to_privkey(cert, privkey);
|
||||
assert_return_code(rc, errno);
|
||||
assert_non_null(privkey->cert);
|
||||
assert_true(privkey->cert_type == SSH_KEYTYPE_ED25519_CERT01);
|
||||
|
||||
assert_int_equal(ssh_key_cmp(privkey, cert, SSH_KEY_CMP_PUBLIC), 0);
|
||||
assert_int_equal(ssh_key_cmp(cert, privkey, SSH_KEY_CMP_PUBLIC), 0);
|
||||
|
||||
/* The private key's cert is already set, another copy should fail. */
|
||||
rc = ssh_pki_copy_cert_to_privkey(cert, privkey);
|
||||
assert_int_equal(rc, SSH_ERROR);
|
||||
|
||||
SSH_KEY_FREE(privkey);
|
||||
SSH_KEY_FREE(pubkey);
|
||||
|
||||
/* Generate different key and try to assign it this certificate */
|
||||
rc = ssh_pki_generate(SSH_KEYTYPE_ED25519, 0, &privkey);
|
||||
assert_return_code(rc, errno);
|
||||
assert_non_null(privkey);
|
||||
rc = ssh_pki_export_privkey_to_pubkey(privkey, &pubkey);
|
||||
assert_return_code(rc, errno);
|
||||
assert_non_null(pubkey);
|
||||
|
||||
rc = ssh_pki_copy_cert_to_privkey(cert, privkey);
|
||||
assert_int_equal(rc, SSH_ERROR);
|
||||
rc = ssh_pki_copy_cert_to_privkey(cert, pubkey);
|
||||
assert_int_equal(rc, SSH_ERROR);
|
||||
|
||||
assert_int_equal(ssh_key_cmp(privkey, cert, SSH_KEY_CMP_PUBLIC), 1);
|
||||
assert_int_equal(ssh_key_cmp(cert, privkey, SSH_KEY_CMP_PUBLIC), 1);
|
||||
|
||||
SSH_KEY_FREE(cert);
|
||||
SSH_KEY_FREE(privkey);
|
||||
SSH_KEY_FREE(pubkey);
|
||||
}
|
||||
|
||||
static void torture_pki_ed25519_publickey_base64(void **state)
|
||||
|
||||
@@ -373,6 +373,7 @@ static void torture_pki_rsa_copy_cert_to_privkey(void **state)
|
||||
ssh_key pubkey = NULL;
|
||||
ssh_key privkey = NULL;
|
||||
ssh_key cert = NULL;
|
||||
enum ssh_keytypes_e type;
|
||||
|
||||
(void)state; /* unused */
|
||||
|
||||
@@ -389,6 +390,13 @@ static void torture_pki_rsa_copy_cert_to_privkey(void **state)
|
||||
assert_return_code(rc, errno);
|
||||
assert_non_null(pubkey);
|
||||
|
||||
type = ssh_key_type(cert);
|
||||
assert_true(type == SSH_KEYTYPE_RSA_CERT01);
|
||||
|
||||
rc = ssh_key_is_public(cert);
|
||||
assert_int_equal(rc, 1);
|
||||
|
||||
/* Import matching private key file and verify the pubkey matches */
|
||||
rc = ssh_pki_import_privkey_base64(torture_get_testkey(SSH_KEYTYPE_RSA, 0),
|
||||
passphrase,
|
||||
NULL,
|
||||
@@ -397,6 +405,9 @@ static void torture_pki_rsa_copy_cert_to_privkey(void **state)
|
||||
assert_return_code(rc, errno);
|
||||
assert_non_null(privkey);
|
||||
|
||||
type = ssh_key_type(privkey);
|
||||
assert_true(type == SSH_KEYTYPE_RSA);
|
||||
|
||||
/* Basic sanity. */
|
||||
rc = ssh_pki_copy_cert_to_privkey(NULL, privkey);
|
||||
assert_int_equal(rc, SSH_ERROR);
|
||||
@@ -416,6 +427,10 @@ static void torture_pki_rsa_copy_cert_to_privkey(void **state)
|
||||
rc = ssh_pki_copy_cert_to_privkey(cert, privkey);
|
||||
assert_return_code(rc, errno);
|
||||
assert_non_null(privkey->cert);
|
||||
assert_true(privkey->cert_type == SSH_KEYTYPE_RSA_CERT01);
|
||||
|
||||
assert_int_equal(ssh_key_cmp(privkey, cert, SSH_KEY_CMP_PUBLIC), 0);
|
||||
assert_int_equal(ssh_key_cmp(cert, privkey, SSH_KEY_CMP_PUBLIC), 0);
|
||||
|
||||
/* The private key's cert is already set, another copy should fail. */
|
||||
rc = ssh_pki_copy_cert_to_privkey(cert, privkey);
|
||||
@@ -437,6 +452,9 @@ static void torture_pki_rsa_copy_cert_to_privkey(void **state)
|
||||
rc = ssh_pki_copy_cert_to_privkey(cert, pubkey);
|
||||
assert_int_equal(rc, SSH_ERROR);
|
||||
|
||||
assert_int_equal(ssh_key_cmp(privkey, cert, SSH_KEY_CMP_PUBLIC), 1);
|
||||
assert_int_equal(ssh_key_cmp(cert, privkey, SSH_KEY_CMP_PUBLIC), 1);
|
||||
|
||||
SSH_KEY_FREE(cert);
|
||||
SSH_KEY_FREE(privkey);
|
||||
SSH_KEY_FREE(pubkey);
|
||||
|
||||
@@ -58,14 +58,8 @@ static int run_on_threads(void *(*func)(void *))
|
||||
}
|
||||
|
||||
for (i = 0; i < NUM_THREADS; ++i) {
|
||||
void *p = NULL;
|
||||
uint64_t *result;
|
||||
|
||||
rc = pthread_join(threads[i], &p);
|
||||
rc = pthread_join(threads[i], NULL);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
result = (uint64_t *)p;
|
||||
assert_null(result);
|
||||
}
|
||||
|
||||
return rc;
|
||||
@@ -164,7 +158,7 @@ static void *thread_pki_rsa_import_pubkey_file(void *threadid)
|
||||
|
||||
SSH_KEY_FREE(pubkey);
|
||||
|
||||
pthread_exit(NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void torture_pki_rsa_import_pubkey_file(void **state)
|
||||
@@ -197,8 +191,7 @@ static void *thread_pki_rsa_import_privkey_base64_NULL_key(void *threadid)
|
||||
NULL,
|
||||
NULL);
|
||||
assert_true(rc == -1);
|
||||
|
||||
pthread_exit(NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void torture_pki_rsa_import_privkey_base64_NULL_key(void **state){
|
||||
@@ -225,7 +218,8 @@ static void *thread_pki_rsa_import_privkey_base64_NULL_str(void *threadid)
|
||||
assert_true(rc == -1);
|
||||
|
||||
SSH_KEY_FREE(key);
|
||||
pthread_exit(NULL);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void torture_pki_rsa_import_privkey_base64_NULL_str(void **state){
|
||||
@@ -267,7 +261,7 @@ static void *thread_pki_rsa_import_privkey_base64(void *threadid)
|
||||
free(key_str);
|
||||
SSH_KEY_FREE(key);
|
||||
|
||||
pthread_exit(NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void torture_pki_rsa_import_privkey_base64(void **state)
|
||||
@@ -310,7 +304,8 @@ static void *thread_pki_rsa_publickey_from_privatekey(void *threadid)
|
||||
|
||||
SSH_KEY_FREE(key);
|
||||
SSH_KEY_FREE(pubkey);
|
||||
pthread_exit(NULL);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void torture_pki_rsa_publickey_from_privatekey(void **state)
|
||||
@@ -383,7 +378,8 @@ static void *thread_pki_rsa_copy_cert_to_privkey(void *threadid)
|
||||
SSH_KEY_FREE(cert);
|
||||
SSH_KEY_FREE(privkey);
|
||||
SSH_KEY_FREE(pubkey);
|
||||
pthread_exit(NULL);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void torture_pki_rsa_copy_cert_to_privkey(void **state)
|
||||
@@ -416,7 +412,8 @@ static void *thread_pki_rsa_import_cert_file(void *threadid)
|
||||
assert_true(rc == 1);
|
||||
|
||||
SSH_KEY_FREE(cert);
|
||||
pthread_exit(NULL);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void torture_pki_rsa_import_cert_file(void **state)
|
||||
@@ -467,7 +464,8 @@ static void *thread_pki_rsa_publickey_base64(void *threadid)
|
||||
free(b64_key);
|
||||
free(key_buf);
|
||||
SSH_KEY_FREE(key);
|
||||
pthread_exit(NULL);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void torture_pki_rsa_publickey_base64(void **state)
|
||||
@@ -531,7 +529,8 @@ static void *thread_pki_rsa_duplicate_key(void *threadid)
|
||||
SSH_KEY_FREE(privkey_dup);
|
||||
SSH_STRING_FREE_CHAR(b64_key);
|
||||
SSH_STRING_FREE_CHAR(b64_key_gen);
|
||||
pthread_exit(NULL);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void torture_pki_rsa_duplicate_key(void **state)
|
||||
@@ -614,7 +613,8 @@ static void *thread_pki_rsa_generate_key(void *threadid)
|
||||
SSH_KEY_FREE(pubkey);
|
||||
|
||||
ssh_free(session);
|
||||
pthread_exit(NULL);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void torture_pki_rsa_generate_key(void **state)
|
||||
@@ -672,7 +672,8 @@ static void *thread_pki_rsa_import_privkey_base64_passphrase(void *threadid)
|
||||
assert_true(rc == -1);
|
||||
SSH_KEY_FREE(key);
|
||||
#endif
|
||||
pthread_exit(NULL);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void torture_pki_rsa_import_privkey_base64_passphrase(void **state)
|
||||
@@ -723,14 +724,8 @@ static void torture_mixed(void **state)
|
||||
|
||||
for (f = 0; f < NUM_TESTS; f++) {
|
||||
for (i = 0; i < NUM_THREADS; ++i) {
|
||||
void *p = NULL;
|
||||
uint64_t *result = NULL;
|
||||
|
||||
rc = pthread_join(threads[f][i], &p);
|
||||
rc = pthread_join(threads[f][i], NULL);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
result = (uint64_t *)p;
|
||||
assert_null(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,6 +140,40 @@
|
||||
fun:FIPS_mode_set
|
||||
fun:OPENSSL_init_library
|
||||
}
|
||||
{
|
||||
Threads + Failed PEM decoder do not play well openssl/openssl#29077
|
||||
Memcheck:Leak
|
||||
match-leak-kinds: definite
|
||||
fun:malloc
|
||||
fun:CRYPTO_malloc
|
||||
fun:CRYPTO_zalloc
|
||||
fun:ossl_rcu_read_lock
|
||||
fun:module_find
|
||||
fun:module_run
|
||||
fun:CONF_modules_load
|
||||
fun:CONF_modules_load_file_ex
|
||||
fun:ossl_config_int
|
||||
fun:ossl_config_int
|
||||
fun:ossl_init_config
|
||||
fun:ossl_init_config_ossl_
|
||||
fun:__pthread_once_slow.isra.0
|
||||
fun:pthread_once@@GLIBC_2.34
|
||||
fun:CRYPTO_THREAD_run_once
|
||||
fun:OPENSSL_init_crypto
|
||||
fun:ossl_provider_doall_activated
|
||||
fun:ossl_algorithm_do_all
|
||||
fun:ossl_method_construct.constprop.0
|
||||
fun:inner_evp_generic_fetch.constprop.0
|
||||
fun:evp_generic_do_all
|
||||
fun:EVP_KEYMGMT_do_all_provided
|
||||
fun:ossl_decoder_ctx_setup_for_pkey
|
||||
fun:OSSL_DECODER_CTX_new_for_pkey
|
||||
fun:pem_read_bio_key_decoder
|
||||
fun:pem_read_bio_key
|
||||
fun:PEM_read_bio_PrivateKey_ex
|
||||
fun:pki_private_key_from_base64
|
||||
...
|
||||
}
|
||||
# Cmocka
|
||||
{
|
||||
This looks like leak from cmocka when the forked server is not properly terminated
|
||||
@@ -207,65 +241,12 @@
|
||||
Memcheck:Leak
|
||||
match-leak-kinds: reachable
|
||||
fun:malloc
|
||||
fun:malloc
|
||||
fun:strdup
|
||||
fun:_dl_load_cache_lookup
|
||||
fun:_dl_map_object
|
||||
fun:dl_open_worker_begin
|
||||
fun:_dl_catch_exception
|
||||
fun:dl_open_worker
|
||||
fun:_dl_catch_exception
|
||||
fun:_dl_open
|
||||
fun:do_dlopen
|
||||
fun:_dl_catch_exception
|
||||
fun:_dl_catch_error
|
||||
fun:dlerror_run
|
||||
fun:__libc_dlopen_mode
|
||||
fun:module_load
|
||||
fun:__nss_module_get_function
|
||||
fun:getaddrinfo
|
||||
...
|
||||
fun:krb5_sname_to_principal
|
||||
...
|
||||
fun:gss_init_sec_context
|
||||
fun:ssh_packet_userauth_gssapi_response
|
||||
fun:ssh_packet_process
|
||||
fun:ssh_packet_socket_callback
|
||||
fun:ssh_socket_pollcallback
|
||||
fun:ssh_poll_ctx_dopoll
|
||||
fun:ssh_handle_packets
|
||||
fun:ssh_handle_packets_termination
|
||||
fun:ssh_userauth_get_response
|
||||
fun:ssh_userauth_gssapi
|
||||
fun:torture_gssapi_auth_server_identity
|
||||
...
|
||||
fun:_cmocka_run_group_tests
|
||||
fun:torture_run_tests
|
||||
fun:main
|
||||
}
|
||||
|
||||
{
|
||||
Reachable memory from getaddrinfo
|
||||
Memcheck:Leak
|
||||
match-leak-kinds: reachable
|
||||
...
|
||||
fun:__nss_module_get_function
|
||||
...
|
||||
fun:getaddrinfo
|
||||
...
|
||||
fun:krb5_sname_to_principal
|
||||
...
|
||||
fun:gss_init_sec_context
|
||||
fun:ssh_packet_userauth_gssapi_response
|
||||
fun:ssh_packet_process
|
||||
fun:ssh_packet_socket_callback
|
||||
fun:ssh_socket_pollcallback
|
||||
fun:ssh_poll_ctx_dopoll
|
||||
fun:ssh_handle_packets
|
||||
fun:ssh_handle_packets_termination
|
||||
fun:ssh_userauth_get_response
|
||||
fun:ssh_userauth_gssapi
|
||||
fun:torture_gssapi_auth_server_identity
|
||||
fun:torture_*
|
||||
...
|
||||
fun:_cmocka_run_group_tests
|
||||
fun:torture_run_tests
|
||||
@@ -290,13 +271,11 @@
|
||||
fun:malloc
|
||||
...
|
||||
fun:krb5_gss_save_error_string
|
||||
fun:UnknownInlinedFun
|
||||
...
|
||||
fun:acquire_cred_context.isra.0
|
||||
fun:acquire_cred_from.isra.0
|
||||
fun:gss_add_cred_from
|
||||
fun:gss_acquire_cred_from
|
||||
...
|
||||
fun:gss_acquire_cred
|
||||
}
|
||||
{
|
||||
error string from gss init sec context
|
||||
@@ -305,7 +284,7 @@
|
||||
fun:malloc
|
||||
...
|
||||
fun:krb5_gss_save_error_string
|
||||
fun:UnknownInlinedFun
|
||||
...
|
||||
fun:krb5_gss_init_sec_context_ext
|
||||
fun:krb5_gss_init_sec_context
|
||||
fun:gss_init_sec_context
|
||||
|
||||
Reference in New Issue
Block a user