diff options
-rw-r--r-- | include/libssh/libssh.h | 2 | ||||
-rw-r--r-- | src/options.c | 86 | ||||
-rw-r--r-- | tests/unittests/torture_options.c | 46 |
3 files changed, 134 insertions, 0 deletions
diff --git a/include/libssh/libssh.h b/include/libssh/libssh.h index 9c60eb3b..0104c8a9 100644 --- a/include/libssh/libssh.h +++ b/include/libssh/libssh.h @@ -427,6 +427,8 @@ LIBSSH_API int ssh_options_getopt(ssh_session session, int *argcptr, char **argv LIBSSH_API int ssh_options_parse_config(ssh_session session, const char *filename); LIBSSH_API int ssh_options_set(ssh_session session, enum ssh_options_e type, const void *value); +LIBSSH_API int ssh_options_get(ssh_session session, enum ssh_options_e type, + char **value); LIBSSH_API int ssh_pcap_file_close(ssh_pcap_file pcap); LIBSSH_API void ssh_pcap_file_free(ssh_pcap_file pcap); LIBSSH_API ssh_pcap_file ssh_pcap_file_new(void); diff --git a/src/options.c b/src/options.c index 105ffac8..f6b1ae9c 100644 --- a/src/options.c +++ b/src/options.c @@ -778,6 +778,92 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type, return 0; } +/** + * @brief This function can get ssh options, it does not support all options provided for + * ssh options set, but mostly those which a user-space program may care about having + * trusted the ssh driver to infer these values from underlaying configuration files. + * It operates only on those SSH_OPTIONS_* which return char*. If you wish to receive + * the port then please use ssh_options_get_port() which returns an unsigned int. + * + * @param session An allocated SSH session structure. + * + * @param type The option type to get. This could be one of the + * following: + * + * - SSH_OPTIONS_HOST: + * The hostname or ip address to connect to (const char *). + * + * - SSH_OPTIONS_USER: + * The username for authentication (const char *).\n + * \n when not explicitly set this will be inferred from the + * ~/.ssh/config file. + * + * - SSH_OPTIONS_IDENTITY: + * Set the identity file name (const char *,format string).\n + * \n + * By default identity, id_dsa and id_rsa are checked.\n + * \n + * The identity file used authenticate with public key. + * It may include "%s" which will be replaced by the + * user home directory. + * + * @param value The value to get into. As a char**, space will be + * allocated by the function for the value, it is + * your responsibility to free the memory using + * ssh_free(). + * + * @return 0 on success, < 0 on error. + */ +int ssh_options_get(ssh_session session, enum ssh_options_e type, char** value) +{ + if (session == NULL) { + return -1; + } + switch(type) + { + case SSH_OPTIONS_HOST: { + if (session->host == NULL) { + ssh_set_error_invalid(session); + return -1; + } + *value = strdup(session->host); + if (*value == NULL) { + ssh_set_error_oom(session); + return -1; + } + break; + } + case SSH_OPTIONS_USER: { + if (session->username == NULL) { + ssh_set_error_invalid(session); + return -1; + } + *value = strdup(session->username); + if (*value == NULL) { + ssh_set_error_oom(session); + return -1; + } + break; + } + case SSH_OPTIONS_IDENTITY: { + if (session->identity == NULL) { + ssh_set_error_invalid(session); + return -1; + } + *value = strdup(session->identity->root->data); + if(*value == NULL){ + ssh_set_error_oom(session); + return -1; + } + break; + } + default: + ssh_set_error(session, SSH_REQUEST_DENIED, "Unknown ssh option %d", type); + return -1; + break; + } + return 0; +} /** * @brief Parse command line arguments. diff --git a/tests/unittests/torture_options.c b/tests/unittests/torture_options.c index 23516944..059095a7 100644 --- a/tests/unittests/torture_options.c +++ b/tests/unittests/torture_options.c @@ -32,6 +32,20 @@ static void torture_options_set_host(void **state) { assert_string_equal(session->username, "guru"); } +static void torture_options_get_host(void **state) { + ssh_session session = *state; + int rc; + char* host = NULL; + + rc = ssh_options_set(session, SSH_OPTIONS_HOST, "localhost"); + assert_true(rc == 0); + assert_string_equal(session->host, "localhost"); + + assert_false(ssh_options_get(session, SSH_OPTIONS_HOST, &host)); + + assert_string_equal(host, "localhost"); +} + static void torture_options_set_port(void **state) { ssh_session session = *state; int rc; @@ -52,6 +66,16 @@ static void torture_options_set_port(void **state) { assert_true(rc == -1); } +static void torture_options_get_user(void **state) { + ssh_session session = *state; + char* user = NULL; + int rc; + rc = ssh_options_set(session, SSH_OPTIONS_USER, "magicaltrevor"); + assert_true(rc == 0); + rc = ssh_options_get(session, SSH_OPTIONS_USER, &user); + assert_string_equal(user, "magicaltrevor"); +} + static void torture_options_set_fd(void **state) { ssh_session session = *state; socket_t fd = 42; @@ -117,14 +141,36 @@ static void torture_options_set_identity(void **state) { assert_string_equal(session->identity->root->next->data, "identity1"); } +static void torture_options_get_identity(void **state) { + ssh_session session = *state; + char *identity = NULL; + int rc; + + rc = ssh_options_set(session, SSH_OPTIONS_ADD_IDENTITY, "identity1"); + assert_true(rc == 0); + rc = ssh_options_get(session, SSH_OPTIONS_IDENTITY, &identity); + assert_true(rc == 0); + assert_string_equal(identity, "identity1"); + + rc = ssh_options_set(session, SSH_OPTIONS_IDENTITY, "identity2"); + assert_true(rc == 0); + assert_string_equal(session->identity->root->data, "identity2"); + rc = ssh_options_get(session, SSH_OPTIONS_IDENTITY, &identity); + assert_true(rc == 0); + assert_string_equal(identity, "identity2"); +} + int torture_run_tests(void) { int rc; const UnitTest tests[] = { unit_test_setup_teardown(torture_options_set_host, setup, teardown), + unit_test_setup_teardown(torture_options_get_host, setup, teardown), unit_test_setup_teardown(torture_options_set_port, setup, teardown), unit_test_setup_teardown(torture_options_set_fd, setup, teardown), unit_test_setup_teardown(torture_options_set_user, setup, teardown), + unit_test_setup_teardown(torture_options_get_user, setup, teardown), unit_test_setup_teardown(torture_options_set_identity, setup, teardown), + unit_test_setup_teardown(torture_options_get_identity, setup, teardown), }; ssh_init(); |