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>
Этот коммит содержится в:
родитель
3ec8babfaf
Коммит
9dc650b7fb
@ -45,7 +45,8 @@ enum ssh_bind_options_e {
|
||||
SSH_BIND_OPTIONS_BANNER,
|
||||
SSH_BIND_OPTIONS_LOG_VERBOSITY,
|
||||
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;
|
||||
|
@ -235,10 +235,12 @@ int ssh_bind_listen(ssh_bind sshbind) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (sshbind->rsa == NULL && sshbind->dsa == NULL && sshbind->ecdsa == NULL) {
|
||||
rc = ssh_bind_import_keys(sshbind);
|
||||
if (rc != SSH_OK) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (sshbind->bindfd == SSH_INVALID_SOCKET) {
|
||||
host = sshbind->bindaddr;
|
||||
@ -430,10 +432,14 @@ 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
|
||||
* only using ssh_bind_accept_fd to manage sockets ourselves.
|
||||
*/
|
||||
if (sshbind->rsa == NULL &&
|
||||
sshbind->dsa == NULL &&
|
||||
sshbind->ecdsa == NULL) {
|
||||
rc = ssh_bind_import_keys(sshbind);
|
||||
if (rc != SSH_OK) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_ECC
|
||||
if (sshbind->ecdsa) {
|
||||
|
@ -1391,6 +1391,9 @@ static int ssh_bind_set_key(ssh_bind sshbind, char **key_loc,
|
||||
* - SSH_BIND_OPTIONS_BANNER:
|
||||
* 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
|
||||
* datatype which should be used is described at the
|
||||
* 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;
|
||||
}
|
||||
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:
|
||||
if (value == NULL) {
|
||||
ssh_set_error_invalid(sshbind);
|
||||
|
@ -199,6 +199,53 @@ static void torture_options_proxycommand(void **state) {
|
||||
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 rc;
|
||||
struct CMUnitTest tests[] = {
|
||||
@ -214,9 +261,14 @@ int torture_run_tests(void) {
|
||||
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();
|
||||
torture_filter_tests(tests);
|
||||
rc = cmocka_run_group_tests(tests, NULL, NULL);
|
||||
rc += cmocka_run_group_tests(sshbind_tests, NULL, NULL);
|
||||
ssh_finalize();
|
||||
return rc;
|
||||
}
|
||||
|
Загрузка…
Ссылка в новой задаче
Block a user