aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorSahana Prasad <sahana@redhat.com>2019-12-20 09:16:29 +0100
committerAndreas Schneider <asn@cryptomilk.org>2019-12-20 16:18:31 +0100
commit2b76abb74c75a6e378d373f8cc2d3d63d2e7d6b3 (patch)
tree0804a006d356168efd9590dbbda04532ff96a446 /tests
parentfa95fe3e1b93f0f6d2a6c8917f806d60d44f7b0b (diff)
downloadlibssh-2b76abb74c75a6e378d373f8cc2d3d63d2e7d6b3.tar.gz
libssh-2b76abb74c75a6e378d373f8cc2d3d63d2e7d6b3.tar.xz
libssh-2b76abb74c75a6e378d373f8cc2d3d63d2e7d6b3.zip
clienttest: Adds a client test that authenticates to the ssh server using ssh_connect through key obtained through PKCS11 URIs.
Signed-Off-by: Sahana Prasad <sahana@redhat.com> Reviewed-by: Jakub Jelen <jjelen@redhat.com> Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
Diffstat (limited to 'tests')
-rw-r--r--tests/client/CMakeLists.txt6
-rw-r--r--tests/client/torture_auth_pkcs11.c260
-rw-r--r--tests/torture.h1
3 files changed, 267 insertions, 0 deletions
diff --git a/tests/client/CMakeLists.txt b/tests/client/CMakeLists.txt
index 70b5de3e..e6adfe36 100644
--- a/tests/client/CMakeLists.txt
+++ b/tests/client/CMakeLists.txt
@@ -24,6 +24,12 @@ if (SCP_EXECUTABLE)
torture_scp)
endif()
+if (WITH_PKCS11_URI)
+ set(LIBSSH_CLIENT_TESTS
+ ${LIBSSH_CLIENT_TESTS}
+ torture_auth_pkcs11)
+endif()
+
if (DEFAULT_C_NO_DEPRECATION_FLAGS)
set_source_files_properties(torture_knownhosts.c
PROPERTIES
diff --git a/tests/client/torture_auth_pkcs11.c b/tests/client/torture_auth_pkcs11.c
new file mode 100644
index 00000000..7c7db8c9
--- /dev/null
+++ b/tests/client/torture_auth_pkcs11.c
@@ -0,0 +1,260 @@
+/*
+ * This file is part of the SSH Library
+ *
+ * Copyright (c) 2010 by Aris Adamantiadis
+ *
+ * The SSH Library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at your
+ * option) any later version.
+ *
+ * The SSH Library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with the SSH Library; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#define LIBSSH_STATIC
+
+#include "torture.h"
+#include "libssh/libssh.h"
+#include "libssh/priv.h"
+#include "libssh/session.h"
+
+#include <errno.h>
+#include <sys/types.h>
+#include <pwd.h>
+
+/* agent_is_running */
+#include "agent.c"
+
+#define LIBSSH_RSA_TESTKEY "id_pkcs11_rsa"
+#define LIBSSH_ECDSA_256_TESTKEY "id_pkcs11_ecdsa_256"
+#define LIBSSH_ECDSA_384_TESTKEY "id_pkcs11_ecdsa_384"
+#define LIBSSH_ECDSA_521_TESTKEY "id_pkcs11_ecdsa_521"
+#define SOFTHSM_CONF "softhsm.conf"
+
+const char template[] = "temp_dir_XXXXXX";
+
+struct pki_st {
+ char *temp_dir;
+ char *orig_dir;
+ char *keys_dir;
+};
+
+static int setup_tokens(void **state, const char *type, const char *obj_name)
+{
+ struct torture_state *s = *state;
+ struct pki_st *test_state = s->private_data;
+ char priv_filename[1024];
+ char *cwd = NULL;
+
+ cwd = test_state->temp_dir;
+ assert_non_null(cwd);
+
+ snprintf(priv_filename, sizeof(priv_filename), "%s%s", test_state->keys_dir, type);
+
+ torture_setup_tokens(cwd, priv_filename, obj_name);
+
+ return 0;
+}
+static int session_setup(void **state)
+{
+ int verbosity = torture_libssh_verbosity();
+ struct torture_state *s = *state;
+ struct passwd *pwd;
+ bool b = false;
+ int rc;
+
+ pwd = getpwnam("bob");
+ assert_non_null(pwd);
+
+ rc = setuid(pwd->pw_uid);
+ assert_return_code(rc, errno);
+
+ s->ssh.session = ssh_new();
+ assert_non_null(s->ssh.session);
+
+ ssh_options_set(s->ssh.session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
+ ssh_options_set(s->ssh.session, SSH_OPTIONS_HOST, TORTURE_SSH_SERVER);
+ /* Make sure no other configuration options from system will get used */
+ rc = ssh_options_set(s->ssh.session, SSH_OPTIONS_PROCESS_CONFIG, &b);
+ assert_ssh_return_code(s->ssh.session, rc);
+
+ /* Make sure we do not interfere with another ssh-agent */
+ unsetenv("SSH_AUTH_SOCK");
+ unsetenv("SSH_AGENT_PID");
+
+ return 0;
+}
+
+static int session_teardown(void **state)
+{
+ struct torture_state *s = *state;
+
+ ssh_disconnect(s->ssh.session);
+ ssh_free(s->ssh.session);
+
+ return 0;
+}
+static int setup_session(void **state)
+{
+ struct torture_state *s = *state;
+ struct pki_st *test_state = NULL;
+ int rc;
+ char conf_path[1024] = {0};
+ char keys_dir[1024] = {0};
+ char *temp_dir;
+
+ test_state = malloc(sizeof(struct pki_st));
+ assert_non_null(test_state);
+
+ s->private_data = test_state;
+
+ test_state->orig_dir = strdup(torture_get_current_working_dir());
+ assert_non_null(test_state->orig_dir);
+
+ temp_dir = torture_make_temp_dir(template);
+ assert_non_null(temp_dir);
+
+ rc = torture_change_dir(temp_dir);
+ assert_int_equal(rc, 0);
+
+ test_state->temp_dir = strdup(torture_get_current_working_dir());
+ assert_non_null(test_state->temp_dir);
+
+ snprintf(keys_dir, sizeof(keys_dir), "%s/tests/keys/pkcs11/", SOURCEDIR);
+
+ test_state->keys_dir = strdup(keys_dir);
+
+ snprintf(conf_path, sizeof(conf_path), "%s/softhsm.conf", test_state->temp_dir);
+ setenv("SOFTHSM2_CONF", conf_path, 1);
+
+ setup_tokens(state, LIBSSH_RSA_TESTKEY, "rsa");
+ setup_tokens(state, LIBSSH_ECDSA_256_TESTKEY, "ecdsa256");
+ setup_tokens(state, LIBSSH_ECDSA_384_TESTKEY, "ecdsa384");
+ setup_tokens(state, LIBSSH_ECDSA_521_TESTKEY, "ecdsa521");
+
+ return 0;
+}
+
+static int sshd_setup(void **state)
+{
+
+ torture_setup_sshd_server(state, true);
+ setup_session(state);
+
+ return 0;
+}
+
+static int sshd_teardown(void **state) {
+
+ struct torture_state *s = *state;
+ struct pki_st *test_state = s->private_data;
+ int rc;
+
+ unsetenv("SOFTHSM2_CONF");
+
+ rc = torture_change_dir(test_state->orig_dir);
+ assert_int_equal(rc, 0);
+
+ rc = torture_rmdirs(test_state->temp_dir);
+ assert_int_equal(rc, 0);
+
+ SAFE_FREE(test_state->temp_dir);
+ SAFE_FREE(test_state->orig_dir);
+ SAFE_FREE(test_state->keys_dir);
+ SAFE_FREE(test_state);
+
+ torture_teardown_sshd_server(state);
+
+ return 0;
+}
+
+static void torture_auth_autopubkey(void **state, const char *obj_name, const char *pin) {
+ struct torture_state *s = *state;
+ ssh_session session = s->ssh.session;
+ int rc;
+ int verbosity = 4;
+ char priv_uri[1042];
+ /* Authenticate as charlie with bob his pubkey */
+ rc = ssh_options_set(session, SSH_OPTIONS_USER, TORTURE_SSH_USER_CHARLIE);
+ assert_int_equal(rc, SSH_OK);
+
+ rc = ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
+ assert_int_equal(rc, SSH_OK);
+
+ //rc = ssh_options_set(session, SSH_OPTIONS_SSH_DIR, "pkcs11");
+ //assert_int_equal(rc, SSH_OK);
+
+ snprintf(priv_uri, sizeof(priv_uri), "pkcs11:token=%s;object=%s;type=private?pin-value=%s",
+ obj_name, obj_name, pin);
+
+ rc = ssh_options_set(session, SSH_OPTIONS_IDENTITY, priv_uri);
+ assert_int_equal(rc, SSH_OK);
+ assert_string_equal(session->opts.identity->root->data, priv_uri);
+
+ rc = ssh_connect(session);
+ assert_int_equal(rc, SSH_OK);
+ rc = ssh_userauth_none(session,NULL);
+ /* This request should return a SSH_REQUEST_DENIED error */
+ if (rc == SSH_ERROR) {
+ assert_int_equal(ssh_get_error_code(session), SSH_REQUEST_DENIED);
+ }
+ rc = ssh_userauth_list(session, NULL);
+ assert_true(rc & SSH_AUTH_METHOD_PUBLICKEY);
+
+ rc = ssh_userauth_publickey_auto(session, NULL, NULL);
+ assert_int_equal(rc, SSH_AUTH_SUCCESS);
+}
+
+static void torture_auth_autopubkey_rsa(void **state) {
+ torture_auth_autopubkey(state, "rsa", "1234");
+}
+
+static void torture_auth_autopubkey_ecdsa_key_256(void **state) {
+ torture_auth_autopubkey(state, "ecdsa256", "1234");
+}
+
+static void torture_auth_autopubkey_ecdsa_key_384(void **state) {
+ torture_auth_autopubkey(state, "ecdsa384", "1234");
+}
+
+static void torture_auth_autopubkey_ecdsa_key_521(void **state) {
+ torture_auth_autopubkey(state, "ecdsa521", "1234");
+}
+
+int torture_run_tests(void) {
+ int rc;
+ struct CMUnitTest tests[] = {
+ cmocka_unit_test_setup_teardown(torture_auth_autopubkey_rsa,
+ session_setup,
+ session_teardown),
+ cmocka_unit_test_setup_teardown(torture_auth_autopubkey_ecdsa_key_256,
+ session_setup,
+ session_teardown),
+ cmocka_unit_test_setup_teardown(torture_auth_autopubkey_ecdsa_key_384,
+ session_setup,
+ session_teardown),
+ cmocka_unit_test_setup_teardown(torture_auth_autopubkey_ecdsa_key_521,
+ session_setup,
+ session_teardown),
+ };
+
+ ssh_session session = ssh_new();
+ int verbosity = SSH_LOG_FUNCTIONS;
+ ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
+ ssh_init();
+ torture_filter_tests(tests);
+ rc = cmocka_run_group_tests(tests, sshd_setup, sshd_teardown);
+ ssh_finalize();
+
+ return rc;
+}
diff --git a/tests/torture.h b/tests/torture.h
index 771130fb..da406cce 100644
--- a/tests/torture.h
+++ b/tests/torture.h
@@ -81,6 +81,7 @@ struct torture_state {
#ifdef WITH_PCAP
ssh_pcap_file plain_pcap;
#endif
+ void *private_data;
};
#ifndef ZERO_STRUCT