1
0
mirror of https://git.libssh.org/projects/libssh.git synced 2025-11-29 01:03:57 +03:00

server: Add option SSH_BIND_OPTIONS_IMPORT_KEY to server

This sets the bind private key directly from an ssh_key struct instead
of reading a file.

Signed-off-by: Alfredo Mazzinghi <am2419@cl.cam.ac.uk>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
This commit is contained in:
Alfredo Mazzinghi
2016-11-12 01:33:37 +00:00
committed by Andreas Schneider
parent 3ec8babfaf
commit 9dc650b7fb
4 changed files with 111 additions and 7 deletions

View File

@@ -45,7 +45,8 @@ enum ssh_bind_options_e {
SSH_BIND_OPTIONS_BANNER, SSH_BIND_OPTIONS_BANNER,
SSH_BIND_OPTIONS_LOG_VERBOSITY, SSH_BIND_OPTIONS_LOG_VERBOSITY,
SSH_BIND_OPTIONS_LOG_VERBOSITY_STR, SSH_BIND_OPTIONS_LOG_VERBOSITY_STR,
SSH_BIND_OPTIONS_ECDSAKEY SSH_BIND_OPTIONS_ECDSAKEY,
SSH_BIND_OPTIONS_IMPORT_KEY
}; };
typedef struct ssh_bind_struct* ssh_bind; typedef struct ssh_bind_struct* ssh_bind;

View File

@@ -235,9 +235,11 @@ int ssh_bind_listen(ssh_bind sshbind) {
return -1; return -1;
} }
rc = ssh_bind_import_keys(sshbind); if (sshbind->rsa == NULL && sshbind->dsa == NULL && sshbind->ecdsa == NULL) {
if (rc != SSH_OK) { rc = ssh_bind_import_keys(sshbind);
return SSH_ERROR; if (rc != SSH_OK) {
return SSH_ERROR;
}
} }
if (sshbind->bindfd == SSH_INVALID_SOCKET) { if (sshbind->bindfd == SSH_INVALID_SOCKET) {
@@ -430,9 +432,13 @@ int ssh_bind_accept_fd(ssh_bind sshbind, ssh_session session, socket_t fd){
* where keys can be imported) on this ssh_bind and are instead * where keys can be imported) on this ssh_bind and are instead
* only using ssh_bind_accept_fd to manage sockets ourselves. * only using ssh_bind_accept_fd to manage sockets ourselves.
*/ */
rc = ssh_bind_import_keys(sshbind); if (sshbind->rsa == NULL &&
if (rc != SSH_OK) { sshbind->dsa == NULL &&
return SSH_ERROR; sshbind->ecdsa == NULL) {
rc = ssh_bind_import_keys(sshbind);
if (rc != SSH_OK) {
return SSH_ERROR;
}
} }
#ifdef HAVE_ECC #ifdef HAVE_ECC

View File

@@ -1391,6 +1391,9 @@ static int ssh_bind_set_key(ssh_bind sshbind, char **key_loc,
* - SSH_BIND_OPTIONS_BANNER: * - SSH_BIND_OPTIONS_BANNER:
* Set the server banner sent to clients (const char *). * Set the server banner sent to clients (const char *).
* *
* - SSH_BIND_OPTIONS_IMPORT_KEY:
* Set the Private Key for the server directly (ssh_key)
*
* @param value The value to set. This is a generic pointer and the * @param value The value to set. This is a generic pointer and the
* datatype which should be used is described at the * datatype which should be used is described at the
* corresponding value of type above. * corresponding value of type above.
@@ -1469,6 +1472,48 @@ int ssh_bind_options_set(ssh_bind sshbind, enum ssh_bind_options_e type,
*bind_key_loc = key; *bind_key_loc = key;
} }
break; break;
case SSH_BIND_OPTIONS_IMPORT_KEY:
if (value == NULL) {
ssh_set_error_invalid(sshbind);
return -1;
} else {
int key_type;
ssh_key *bind_key_loc = NULL;
ssh_key key = (ssh_key)value;
key_type = ssh_key_type(key);
switch (key_type) {
case SSH_KEYTYPE_DSS:
bind_key_loc = &sshbind->dsa;
break;
case SSH_KEYTYPE_ECDSA:
#ifdef HAVE_ECC
bind_key_loc = &sshbind->ecdsa;
#else
ssh_set_error(sshbind,
SSH_FATAL,
"ECDSA key used and libssh compiled "
"without ECDSA support");
#endif
break;
case SSH_KEYTYPE_RSA:
case SSH_KEYTYPE_RSA1:
bind_key_loc = &sshbind->rsa;
break;
case SSH_KEYTYPE_ED25519:
bind_key_loc = &sshbind->ed25519;
break;
default:
ssh_set_error(sshbind,
SSH_FATAL,
"Unsupported key type %d", key_type);
}
if (bind_key_loc == NULL)
return -1;
ssh_key_free(*bind_key_loc);
*bind_key_loc = key;
}
break;
case SSH_BIND_OPTIONS_BINDADDR: case SSH_BIND_OPTIONS_BINDADDR:
if (value == NULL) { if (value == NULL) {
ssh_set_error_invalid(sshbind); ssh_set_error_invalid(sshbind);

View File

@@ -199,6 +199,53 @@ static void torture_options_proxycommand(void **state) {
assert_null(session->opts.ProxyCommand); assert_null(session->opts.ProxyCommand);
} }
/* sshbind options */
static int sshbind_setup(void **state)
{
ssh_bind bind = ssh_bind_new();
*state = bind;
return 0;
}
static int sshbind_teardown(void **state)
{
ssh_bind_free(*state);
return 0;
}
static void torture_bind_options_import_key(void **state)
{
ssh_bind bind = *state;
int rc;
ssh_key key = ssh_key_new();
const char *base64_key;
/* set null */
rc = ssh_bind_options_set(bind, SSH_BIND_OPTIONS_IMPORT_KEY, NULL);
assert_int_equal(rc, -1);
/* set invalid key */
rc = ssh_bind_options_set(bind, SSH_BIND_OPTIONS_IMPORT_KEY, key);
assert_int_equal(rc, -1);
/* set rsa key */
base64_key = torture_get_testkey(SSH_KEYTYPE_RSA, 0, 0);
ssh_pki_import_privkey_base64(base64_key, NULL, NULL, NULL, &key);
rc = ssh_bind_options_set(bind, SSH_BIND_OPTIONS_IMPORT_KEY, key);
assert_int_equal(rc, 0);
/* set dsa key */
base64_key = torture_get_testkey(SSH_KEYTYPE_DSS, 0, 0);
ssh_pki_import_privkey_base64(base64_key, NULL, NULL, NULL, &key);
rc = ssh_bind_options_set(bind, SSH_BIND_OPTIONS_IMPORT_KEY, key);
assert_int_equal(rc, 0);
/* set ecdsa key */
base64_key = torture_get_testkey(SSH_KEYTYPE_ECDSA, 512, 0);
ssh_pki_import_privkey_base64(base64_key, NULL, NULL, NULL, &key);
rc = ssh_bind_options_set(bind, SSH_BIND_OPTIONS_IMPORT_KEY, key);
assert_int_equal(rc, 0);
}
int torture_run_tests(void) { int torture_run_tests(void) {
int rc; int rc;
struct CMUnitTest tests[] = { struct CMUnitTest tests[] = {
@@ -214,9 +261,14 @@ int torture_run_tests(void) {
cmocka_unit_test_setup_teardown(torture_options_proxycommand, setup, teardown), cmocka_unit_test_setup_teardown(torture_options_proxycommand, setup, teardown),
}; };
struct CMUnitTest sshbind_tests[] = {
cmocka_unit_test_setup_teardown(torture_bind_options_import_key, sshbind_setup, sshbind_teardown),
};
ssh_init(); ssh_init();
torture_filter_tests(tests); torture_filter_tests(tests);
rc = cmocka_run_group_tests(tests, NULL, NULL); rc = cmocka_run_group_tests(tests, NULL, NULL);
rc += cmocka_run_group_tests(sshbind_tests, NULL, NULL);
ssh_finalize(); ssh_finalize();
return rc; return rc;
} }