aboutsummaryrefslogtreecommitdiff
path: root/tests/client/torture_auth.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/client/torture_auth.c')
-rw-r--r--tests/client/torture_auth.c712
1 files changed, 546 insertions, 166 deletions
diff --git a/tests/client/torture_auth.c b/tests/client/torture_auth.c
index 24ecc507..77b7bd1f 100644
--- a/tests/client/torture_auth.c
+++ b/tests/client/torture_auth.c
@@ -32,8 +32,7 @@
#include <sys/types.h>
#include <pwd.h>
-/* agent_is_running */
-#include "agent.c"
+#include "torture_auth_common.c"
static int sshd_setup(void **state)
{
@@ -112,7 +111,7 @@ static int agent_setup(void **state)
char ssh_agent_cmd[4096];
char ssh_agent_sock[1024];
char ssh_agent_pidfile[1024];
- char bob_ssh_key[1024];
+ char ssh_key_add[1024];
struct passwd *pwd;
int rc;
@@ -149,38 +148,12 @@ static int agent_setup(void **state)
setenv("SSH_AUTH_SOCK", ssh_agent_sock, 1);
setenv("TORTURE_SSH_AGENT_PIDFILE", ssh_agent_pidfile, 1);
- snprintf(bob_ssh_key,
- sizeof(bob_ssh_key),
+ snprintf(ssh_key_add,
+ sizeof(ssh_key_add),
"ssh-add %s/.ssh/id_rsa",
pwd->pw_dir);
- rc = system(bob_ssh_key);
- assert_return_code(rc, errno);
-
- return 0;
-}
-
-static int agent_cert_setup(void **state)
-{
- char bob_alt_ssh_key[1024];
- struct passwd *pwd;
- int rc;
-
- rc = agent_setup(state);
- if (rc != 0) {
- return rc;
- }
-
- pwd = getpwnam("bob");
- assert_non_null(pwd);
-
- /* remove all keys, load alternative key + cert */
- snprintf(bob_alt_ssh_key,
- sizeof(bob_alt_ssh_key),
- "ssh-add -D && ssh-add %s/.ssh_cert/id_rsa",
- pwd->pw_dir);
-
- rc = system(bob_alt_ssh_key);
+ rc = system(ssh_key_add);
assert_return_code(rc, errno);
return 0;
@@ -257,6 +230,143 @@ static void torture_auth_none_nonblocking(void **state) {
}
+/* Setting MaxAuthTries 0 makes libssh hang. The option is not practical,
+ * but simulates setting low value and requiring multiple authentication
+ * methods to succeed (T233)
+ */
+static void torture_auth_none_max_tries(void **state) {
+ struct torture_state *s = *state;
+ ssh_session session = s->ssh.session;
+ int rc;
+ const char *sshd_config = "MaxAuthTries 0";
+
+ torture_update_sshd_config(state, sshd_config);
+
+ rc = ssh_options_set(session, SSH_OPTIONS_USER, TORTURE_SSH_USER_BOB);
+ assert_int_equal(rc, SSH_OK);
+
+ rc = ssh_connect(session);
+ assert_int_equal(rc, SSH_OK);
+
+ rc = ssh_userauth_none(session,NULL);
+ assert_int_equal(rc, SSH_AUTH_DENIED);
+
+ /* This request should return a SSH_REQUEST_DENIED error */
+ if (rc == SSH_ERROR) {
+ assert_int_equal(ssh_get_error_code(session), SSH_REQUEST_DENIED);
+ }
+
+ /* Reset config back to defaults */
+ torture_update_sshd_config(state, "");
+}
+
+
+static void torture_auth_pubkey(void **state) {
+ struct torture_state *s = *state;
+ ssh_session session = s->ssh.session;
+ char bob_ssh_key[1024];
+ ssh_key privkey = NULL;
+ struct passwd *pwd = NULL;
+ int rc;
+
+ pwd = getpwnam("bob");
+ assert_non_null(pwd);
+
+ snprintf(bob_ssh_key,
+ sizeof(bob_ssh_key),
+ "%s/.ssh/id_rsa",
+ pwd->pw_dir);
+
+ /* Authenticate as alice with bob his pubkey */
+ rc = ssh_options_set(session, SSH_OPTIONS_USER, TORTURE_SSH_USER_ALICE);
+ assert_int_equal(rc, SSH_OK);
+
+ 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_pki_import_privkey_file(bob_ssh_key, NULL, NULL, NULL, &privkey);
+ assert_int_equal(rc, SSH_OK);
+
+ /* negative tests */
+ rc = ssh_userauth_try_publickey(NULL, NULL, privkey);
+ assert_int_equal(rc, SSH_AUTH_ERROR);
+ rc = ssh_userauth_try_publickey(session, NULL, NULL);
+ assert_int_equal(rc, SSH_AUTH_ERROR);
+
+ rc = ssh_userauth_try_publickey(session, NULL, privkey);
+ assert_int_equal(rc, SSH_AUTH_SUCCESS);
+
+ /* negative tests */
+ rc = ssh_userauth_publickey(NULL, NULL, privkey);
+ assert_int_equal(rc, SSH_AUTH_ERROR);
+ rc = ssh_userauth_publickey(session, NULL, NULL);
+ assert_int_equal(rc, SSH_AUTH_ERROR);
+
+ rc = ssh_userauth_publickey(session, NULL, privkey);
+ assert_int_equal(rc, SSH_AUTH_SUCCESS);
+
+ SSH_KEY_FREE(privkey);
+}
+
+static void torture_auth_pubkey_nonblocking(void **state) {
+ struct torture_state *s = *state;
+ ssh_session session = s->ssh.session;
+ char bob_ssh_key[1024];
+ ssh_key privkey = NULL;
+ struct passwd *pwd = NULL;
+ int rc;
+
+ pwd = getpwnam("bob");
+ assert_non_null(pwd);
+
+ snprintf(bob_ssh_key,
+ sizeof(bob_ssh_key),
+ "%s/.ssh/id_rsa",
+ pwd->pw_dir);
+
+ /* Authenticate as alice with bob his pubkey */
+ rc = ssh_options_set(session, SSH_OPTIONS_USER, TORTURE_SSH_USER_ALICE);
+ assert_int_equal(rc, SSH_OK);
+
+ rc = ssh_connect(session);
+ assert_int_equal(rc, SSH_OK);
+
+ ssh_set_blocking(session, 0);
+
+ do {
+ rc = ssh_userauth_none(session,NULL);
+ } while (rc == SSH_AUTH_AGAIN);
+ assert_int_equal(rc, SSH_AUTH_DENIED);
+ 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_pki_import_privkey_file(bob_ssh_key, NULL, NULL, NULL, &privkey);
+ assert_int_equal(rc, SSH_OK);
+
+ do {
+ rc = ssh_userauth_try_publickey(session, NULL, privkey);
+ } while (rc == SSH_AUTH_AGAIN);
+ assert_int_equal(rc, SSH_AUTH_SUCCESS);
+
+ do {
+ rc = ssh_userauth_publickey(session, NULL, privkey);
+ } while (rc == SSH_AUTH_AGAIN);
+ assert_int_equal(rc, SSH_AUTH_SUCCESS);
+
+ SSH_KEY_FREE(privkey);
+}
+
static void torture_auth_autopubkey(void **state) {
struct torture_state *s = *state;
ssh_session session = s->ssh.session;
@@ -281,6 +391,96 @@ static void torture_auth_autopubkey(void **state) {
assert_int_equal(rc, SSH_AUTH_SUCCESS);
}
+struct torture_auth_autopubkey_protected_data {
+ ssh_session session;
+ int n_calls;
+};
+
+static int
+torture_auth_autopubkey_protected_auth_function (const char *prompt, char *buf, size_t len,
+ int echo, int verify, void *userdata)
+{
+ int rc;
+ char *id, *expected_id;
+ struct torture_auth_autopubkey_protected_data *data = userdata;
+
+ assert_true(prompt != NULL);
+ assert_int_equal(echo, 0);
+ assert_int_equal(verify, 0);
+
+ expected_id = ssh_path_expand_escape(data->session, "%d/id_rsa_protected");
+ assert_true(expected_id != NULL);
+
+ rc = ssh_userauth_publickey_auto_get_current_identity(data->session, &id);
+ assert_int_equal(rc, SSH_OK);
+
+ assert_string_equal(expected_id, id);
+
+ ssh_string_free_char(id);
+ ssh_string_free_char(expected_id);
+
+ data->n_calls += 1;
+ strncpy(buf, "secret", len);
+ return 0;
+}
+
+static void torture_auth_autopubkey_protected(void **state) {
+ struct torture_state *s = *state;
+ ssh_session session = s->ssh.session;
+ char *id;
+ int rc;
+
+ struct torture_auth_autopubkey_protected_data data = {
+ .session = session,
+ .n_calls = 0
+ };
+
+ struct ssh_callbacks_struct callbacks = {
+ .userdata = &data,
+ .auth_function = torture_auth_autopubkey_protected_auth_function
+ };
+
+ /* no session pointer */
+ rc = ssh_userauth_publickey_auto_get_current_identity(NULL, &id);
+ assert_int_equal(rc, SSH_ERROR);
+
+ /* no result pointer */
+ rc = ssh_userauth_publickey_auto_get_current_identity(session, NULL);
+ assert_int_equal(rc, SSH_ERROR);
+
+ /* no auto auth going on */
+ rc = ssh_userauth_publickey_auto_get_current_identity(session, &id);
+ assert_int_equal(rc, SSH_ERROR);
+
+ ssh_callbacks_init(&callbacks);
+ ssh_set_callbacks(session, &callbacks);
+
+ /* Authenticate as alice with bob his pubkey */
+ rc = ssh_options_set(session, SSH_OPTIONS_USER, TORTURE_SSH_USER_ALICE);
+ assert_int_equal(rc, SSH_OK);
+
+ /* Try id_rsa_protected first.
+ */
+ rc = ssh_options_set(session, SSH_OPTIONS_IDENTITY, "%d/id_rsa_protected");
+ assert_int_equal(rc, SSH_OK);
+
+ 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);
+
+ assert_int_equal (data.n_calls, 1);
+}
+
static void torture_auth_autopubkey_nonblocking(void **state) {
struct torture_state *s = *state;
ssh_session session = s->ssh.session;
@@ -311,7 +511,11 @@ static void torture_auth_autopubkey_nonblocking(void **state) {
assert_int_equal(rc, SSH_AUTH_SUCCESS);
}
-static void torture_auth_kbdint(void **state) {
+static void
+torture_auth_kbdint(void **state,
+ const char *password,
+ enum ssh_auth_e res)
+{
struct torture_state *s = *state;
ssh_session session = s->ssh.session;
int rc;
@@ -334,19 +538,35 @@ static void torture_auth_kbdint(void **state) {
assert_int_equal(rc, SSH_AUTH_INFO);
assert_int_equal(ssh_userauth_kbdint_getnprompts(session), 1);
- rc = ssh_userauth_kbdint_setanswer(session, 0, TORTURE_SSH_USER_BOB_PASSWORD);
+ rc = ssh_userauth_kbdint_setanswer(session, 0, password);
assert_false(rc < 0);
rc = ssh_userauth_kbdint(session, NULL, NULL);
/* Sometimes, SSH server send an empty query at the end of exchange */
- if(rc == SSH_AUTH_INFO) {
+ if (rc == SSH_AUTH_INFO) {
assert_int_equal(ssh_userauth_kbdint_getnprompts(session), 0);
rc = ssh_userauth_kbdint(session, NULL, NULL);
}
- assert_int_equal(rc, SSH_AUTH_SUCCESS);
+ assert_int_equal(rc, res);
}
-static void torture_auth_kbdint_nonblocking(void **state) {
+static void
+torture_auth_kbdint_good(void **state)
+{
+ torture_auth_kbdint(state, TORTURE_SSH_USER_BOB_PASSWORD, SSH_AUTH_SUCCESS);
+}
+
+static void
+torture_auth_kbdint_bad(void **state)
+{
+ torture_auth_kbdint(state, "bad password stample", SSH_AUTH_DENIED);
+}
+
+static void
+torture_auth_kbdint_nonblocking(void **state,
+ const char *password,
+ enum ssh_auth_e res)
+{
struct torture_state *s = *state;
ssh_session session = s->ssh.session;
int rc;
@@ -357,9 +577,9 @@ static void torture_auth_kbdint_nonblocking(void **state) {
rc = ssh_connect(session);
assert_int_equal(rc, SSH_OK);
- ssh_set_blocking(session,0);
+ ssh_set_blocking(session, 0);
do {
- rc = ssh_userauth_none(session, NULL);
+ rc = ssh_userauth_none(session, NULL);
} while (rc == SSH_AUTH_AGAIN);
/* This request should return a SSH_REQUEST_DENIED error */
@@ -374,23 +594,41 @@ static void torture_auth_kbdint_nonblocking(void **state) {
} while (rc == SSH_AUTH_AGAIN);
assert_int_equal(rc, SSH_AUTH_INFO);
assert_int_equal(ssh_userauth_kbdint_getnprompts(session), 1);
- rc = ssh_userauth_kbdint_setanswer(session, 0, TORTURE_SSH_USER_BOB_PASSWORD);
+ rc = ssh_userauth_kbdint_setanswer(session, 0, password);
assert_false(rc < 0);
do {
rc = ssh_userauth_kbdint(session, NULL, NULL);
} while (rc == SSH_AUTH_AGAIN);
/* Sometimes, SSH server send an empty query at the end of exchange */
- if(rc == SSH_AUTH_INFO) {
+ if (rc == SSH_AUTH_INFO) {
assert_int_equal(ssh_userauth_kbdint_getnprompts(session), 0);
do {
rc = ssh_userauth_kbdint(session, NULL, NULL);
} while (rc == SSH_AUTH_AGAIN);
}
- assert_int_equal(rc, SSH_AUTH_SUCCESS);
+ assert_int_equal(rc, res);
+}
+
+static void
+torture_auth_kbdint_nonblocking_good(void **state)
+{
+ torture_auth_kbdint_nonblocking(state,
+ TORTURE_SSH_USER_BOB_PASSWORD,
+ SSH_AUTH_SUCCESS);
+}
+
+static void
+torture_auth_kbdint_nonblocking_bad(void **state)
+{
+ torture_auth_kbdint_nonblocking(state,
+ "bad password stample",
+ SSH_AUTH_DENIED);
}
-static void torture_auth_password(void **state) {
+static void
+torture_auth_password(void **state, const char *password, enum ssh_auth_e res)
+{
struct torture_state *s = *state;
ssh_session session = s->ssh.session;
int rc;
@@ -409,11 +647,29 @@ static void torture_auth_password(void **state) {
rc = ssh_userauth_list(session, NULL);
assert_true(rc & SSH_AUTH_METHOD_PASSWORD);
- rc = ssh_userauth_password(session, NULL, TORTURE_SSH_USER_BOB_PASSWORD);
- assert_int_equal(rc, SSH_AUTH_SUCCESS);
+ rc = ssh_userauth_password(session, NULL, password);
+ assert_int_equal(rc, res);
+}
+
+static void
+torture_auth_password_good(void **state)
+{
+ torture_auth_password(state,
+ TORTURE_SSH_USER_BOB_PASSWORD,
+ SSH_AUTH_SUCCESS);
}
-static void torture_auth_password_nonblocking(void **state) {
+static void
+torture_auth_password_bad(void **state)
+{
+ torture_auth_password(state, "bad password stample", SSH_AUTH_DENIED);
+}
+
+static void
+torture_auth_password_nonblocking(void **state,
+ const char *password,
+ enum ssh_auth_e res)
+{
struct torture_state *s = *state;
ssh_session session = s->ssh.session;
int rc;
@@ -426,7 +682,7 @@ static void torture_auth_password_nonblocking(void **state) {
ssh_set_blocking(session,0);
do {
- rc = ssh_userauth_none(session, NULL);
+ rc = ssh_userauth_none(session, NULL);
} while (rc == SSH_AUTH_AGAIN);
/* This request should return a SSH_REQUEST_DENIED error */
@@ -438,16 +694,51 @@ static void torture_auth_password_nonblocking(void **state) {
assert_true(rc & SSH_AUTH_METHOD_PASSWORD);
do {
- rc = ssh_userauth_password(session, NULL, TORTURE_SSH_USER_BOB_PASSWORD);
- } while(rc==SSH_AUTH_AGAIN);
+ rc = ssh_userauth_password(session, NULL, password);
+ } while (rc == SSH_AUTH_AGAIN);
- assert_int_equal(rc, SSH_AUTH_SUCCESS);
+ assert_int_equal(rc, res);
+}
+
+static void
+torture_auth_password_nonblocking_good(void **state)
+{
+ torture_auth_password_nonblocking(state,
+ TORTURE_SSH_USER_BOB_PASSWORD,
+ SSH_AUTH_SUCCESS);
+}
+
+static void
+torture_auth_password_nonblocking_bad(void **state)
+{
+ torture_auth_password_nonblocking(state,
+ "bad password stample",
+ SSH_AUTH_DENIED);
}
-static void torture_auth_agent(void **state) {
+/* TODO cover the case:
+ * * when there is accompanying certificate (identities only + agent)
+ * * export private key to public key during _auto() authentication.
+ * this needs to be a encrypted private key in PEM format without
+ * accompanying public key.
+ */
+static void torture_auth_agent_identities_only(void **state)
+{
struct torture_state *s = *state;
ssh_session session = s->ssh.session;
+ char bob_ssh_key[1024];
+ struct passwd *pwd = NULL;
int rc;
+ int identities_only = 1;
+ char *id = NULL;
+
+ pwd = getpwnam("bob");
+ assert_non_null(pwd);
+
+ snprintf(bob_ssh_key,
+ sizeof(bob_ssh_key),
+ "%s/.ssh/id_rsa",
+ pwd->pw_dir);
if (!ssh_agent_is_running(session)){
print_message("*** Agent not running. Test ignored\n");
@@ -456,37 +747,18 @@ static void torture_auth_agent(void **state) {
rc = ssh_options_set(session, SSH_OPTIONS_USER, TORTURE_SSH_USER_ALICE);
assert_int_equal(rc, SSH_OK);
- rc = ssh_connect(session);
+ rc = ssh_options_set(session, SSH_OPTIONS_IDENTITIES_ONLY, &identities_only);
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_agent(session, NULL);
- assert_int_equal(rc, SSH_AUTH_SUCCESS);
-}
-
-static void torture_auth_agent_nonblocking(void **state) {
- struct torture_state *s = *state;
- ssh_session session = s->ssh.session;
- int rc;
-
- if (!ssh_agent_is_running(session)){
- print_message("*** Agent not running. Test ignored\n");
- return;
+ /* Remove the default identities */
+ while ((id = ssh_list_pop_head(char *, session->opts.identity_non_exp)) != NULL) {
+ SAFE_FREE(id);
}
- rc = ssh_options_set(session, SSH_OPTIONS_USER, TORTURE_SSH_USER_ALICE);
- assert_int_equal(rc, SSH_OK);
rc = ssh_connect(session);
assert_int_equal(rc, SSH_OK);
- rc = ssh_userauth_none(session,NULL);
+ 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);
@@ -494,111 +766,74 @@ static void torture_auth_agent_nonblocking(void **state) {
rc = ssh_userauth_list(session, NULL);
assert_true(rc & SSH_AUTH_METHOD_PUBLICKEY);
- ssh_set_blocking(session,0);
+ /* Should fail as key is not in config */
+ rc = ssh_userauth_agent(session, NULL);
+ assert_ssh_return_code_equal(session, rc, SSH_AUTH_DENIED);
- do {
- rc = ssh_userauth_agent(session, NULL);
- } while (rc == SSH_AUTH_AGAIN);
- assert_int_equal(rc, SSH_AUTH_SUCCESS);
+ /* Re-add a key */
+ rc = ssh_list_append(session->opts.identity, strdup(bob_ssh_key));
+ assert_int_equal(rc, SSH_OK);
+
+ /* Should succeed as key now in config/options */
+ rc = ssh_userauth_agent(session, NULL);
+ assert_ssh_return_code(session, rc);
}
-static void torture_auth_cert(void **state) {
+static void torture_auth_agent_identities_only_protected(void **state)
+{
struct torture_state *s = *state;
ssh_session session = s->ssh.session;
- ssh_key privkey = NULL;
- ssh_key cert = NULL;
char bob_ssh_key[1024];
- char bob_ssh_cert[2048];
struct passwd *pwd;
int rc;
+ int identities_only = 1;
+ char *id = NULL;
pwd = getpwnam("bob");
assert_non_null(pwd);
snprintf(bob_ssh_key,
sizeof(bob_ssh_key),
- "%s/.ssh_cert/id_rsa",
+ "%s/.ssh/id_rsa_protected",
pwd->pw_dir);
- snprintf(bob_ssh_cert,
- sizeof(bob_ssh_cert),
- "%s-cert.pub",
- bob_ssh_key);
- /* cert has been signed for login as alice */
+ if (!ssh_agent_is_running(session)){
+ print_message("*** Agent not running. Test ignored\n");
+ return;
+ }
rc = ssh_options_set(session, SSH_OPTIONS_USER, TORTURE_SSH_USER_ALICE);
assert_int_equal(rc, SSH_OK);
- rc = ssh_connect(session);
- assert_int_equal(rc, SSH_OK);
-
- rc = ssh_pki_import_privkey_file(bob_ssh_key, NULL, NULL, NULL, &privkey);
+ rc = ssh_options_set(session, SSH_OPTIONS_IDENTITIES_ONLY, &identities_only);
assert_int_equal(rc, SSH_OK);
- rc = ssh_pki_import_cert_file(bob_ssh_cert, &cert);
- assert_int_equal(rc, SSH_OK);
+ /* Remove the default identities */
+ while ((id = ssh_list_pop_head(char *, session->opts.identity_non_exp)) != NULL) {
+ SAFE_FREE(id);
+ }
- rc = ssh_pki_copy_cert_to_privkey(cert, privkey);
+ rc = ssh_connect(session);
assert_int_equal(rc, SSH_OK);
- rc = ssh_userauth_try_publickey(session, NULL, cert);
- assert_int_equal(rc, SSH_AUTH_SUCCESS);
-
- rc = ssh_userauth_publickey(session, NULL, privkey);
- assert_int_equal(rc, SSH_AUTH_SUCCESS);
-
- SSH_KEY_FREE(privkey);
- SSH_KEY_FREE(cert);
-}
-
-static void torture_auth_agent_cert(void **state)
-{
- struct torture_state *s = *state;
- ssh_session session = s->ssh.session;
- int rc;
-
- /* Skip this test if in FIPS mode.
- *
- * OpenSSH agent has a bug which makes it to not use SHA2 in signatures when
- * using certificates. It always uses SHA1.
- *
- * This should be removed as soon as OpenSSH agent bug is fixed.
- * (see https://gitlab.com/libssh/libssh-mirror/merge_requests/34) */
- if (ssh_fips_mode()) {
- skip();
- } else {
- /* After the bug is solved, this also should be removed */
- rc = ssh_options_set(session, SSH_OPTIONS_PUBLICKEY_ACCEPTED_TYPES,
- "ssh-rsa-cert-v01@openssh.com");
- 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);
- /* Setup loads a different key, tests are exactly the same. */
- torture_auth_agent(state);
-}
-
-static void torture_auth_agent_cert_nonblocking(void **state)
-{
- struct torture_state *s = *state;
- ssh_session session = s->ssh.session;
- int rc;
+ /* Should fail as key is not in config */
+ rc = ssh_userauth_agent(session, NULL);
+ assert_ssh_return_code_equal(session, rc, SSH_AUTH_DENIED);
- /* Skip this test if in FIPS mode.
- *
- * OpenSSH agent has a bug which makes it to not use SHA2 in signatures when
- * using certificates. It always uses SHA1.
- *
- * This should be removed as soon as OpenSSH agent bug is fixed.
- * (see https://gitlab.com/libssh/libssh-mirror/merge_requests/34) */
- if (ssh_fips_mode()) {
- skip();
- } else {
- /* After the bug is solved, this also should be removed */
- rc = ssh_options_set(session, SSH_OPTIONS_PUBLICKEY_ACCEPTED_TYPES,
- "ssh-rsa-cert-v01@openssh.com");
- assert_int_equal(rc, SSH_OK);
- }
+ /* Re-add a key */
+ rc = ssh_list_append(session->opts.identity, strdup(bob_ssh_key));
+ assert_int_equal(rc, SSH_OK);
- torture_auth_agent_nonblocking(state);
+ /* Should succeed as key now in config */
+ rc = ssh_userauth_agent(session, NULL);
+ assert_ssh_return_code(session, rc);
}
static void torture_auth_pubkey_types(void **state)
@@ -658,7 +893,7 @@ static void torture_auth_pubkey_types_ecdsa(void **state)
rc = ssh_userauth_list(session, NULL);
assert_true(rc & SSH_AUTH_METHOD_PUBLICKEY);
- /* We have only the 256b key -- whitelisting only larger should fail */
+ /* We have only the 256b key -- allowlisting only larger should fail */
rc = ssh_options_set(session, SSH_OPTIONS_PUBLICKEY_ACCEPTED_TYPES,
"ecdsa-sha2-nistp384");
assert_ssh_return_code(session, rc);
@@ -795,7 +1030,7 @@ static void torture_auth_pubkey_types_ecdsa_nonblocking(void **state)
ssh_set_blocking(session, 0);
do {
- rc = ssh_userauth_none(session, NULL);
+ rc = ssh_userauth_none(session, NULL);
} while (rc == SSH_AUTH_AGAIN);
/* This request should return a SSH_REQUEST_DENIED error */
@@ -806,7 +1041,7 @@ static void torture_auth_pubkey_types_ecdsa_nonblocking(void **state)
rc = ssh_userauth_list(session, NULL);
assert_true(rc & SSH_AUTH_METHOD_PUBLICKEY);
- /* We have only the 256b key -- whitelisting only larger should fail */
+ /* We have only the 256b key -- allowlisting only larger should fail */
rc = ssh_options_set(session, SSH_OPTIONS_PUBLICKEY_ACCEPTED_TYPES,
"ecdsa-sha2-nistp384");
assert_ssh_return_code(session, rc);
@@ -892,6 +1127,124 @@ static void torture_auth_pubkey_types_ed25519_nonblocking(void **state)
} while (rc == SSH_AUTH_AGAIN);
assert_int_equal(rc, SSH_AUTH_SUCCESS);
+ SSH_KEY_FREE(privkey);
+}
+
+static void torture_auth_pubkey_rsa_key_size(void **state)
+{
+ struct torture_state *s = *state;
+ ssh_session session = s->ssh.session;
+ char bob_ssh_key[1024];
+ ssh_key privkey = NULL;
+ struct passwd *pwd;
+ int rc;
+ unsigned int limit = 4096;
+
+ pwd = getpwnam("bob");
+ assert_non_null(pwd);
+
+ snprintf(bob_ssh_key,
+ sizeof(bob_ssh_key),
+ "%s/.ssh/id_rsa",
+ pwd->pw_dir);
+
+ rc = ssh_options_set(session, SSH_OPTIONS_USER, TORTURE_SSH_USER_ALICE);
+ assert_ssh_return_code(session, rc);
+
+ rc = ssh_connect(session);
+ assert_ssh_return_code(session, rc);
+
+ 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);
+
+ /* set unreasonable large minimum key size to trigger the condition */
+ rc = ssh_options_set(session, SSH_OPTIONS_RSA_MIN_SIZE, &limit); /* larger than the test key */
+ assert_ssh_return_code(session, rc);
+
+ /* Import the RSA private key */
+ rc = ssh_pki_import_privkey_file(bob_ssh_key, NULL, NULL, NULL, &privkey);
+ assert_int_equal(rc, SSH_OK);
+
+ rc = ssh_userauth_publickey(session, NULL, privkey);
+ assert_int_equal(rc, SSH_AUTH_DENIED);
+
+ /* revert to default values which should work also in FIPS mode */
+ limit = 0;
+ rc = ssh_options_set(session, SSH_OPTIONS_RSA_MIN_SIZE, &limit);
+ assert_ssh_return_code(session, rc);
+
+ rc = ssh_userauth_publickey(session, NULL, privkey);
+ assert_int_equal(rc, SSH_AUTH_SUCCESS);
+
+ SSH_KEY_FREE(privkey);
+}
+
+static void torture_auth_pubkey_rsa_key_size_nonblocking(void **state)
+{
+ struct torture_state *s = *state;
+ ssh_session session = s->ssh.session;
+ char bob_ssh_key[1024];
+ ssh_key privkey = NULL;
+ struct passwd *pwd;
+ int rc;
+ unsigned int limit = 4096;
+
+ pwd = getpwnam("bob");
+ assert_non_null(pwd);
+
+ snprintf(bob_ssh_key,
+ sizeof(bob_ssh_key),
+ "%s/.ssh/id_rsa",
+ pwd->pw_dir);
+
+ rc = ssh_options_set(session, SSH_OPTIONS_USER, TORTURE_SSH_USER_ALICE);
+ assert_ssh_return_code(session, rc);
+
+ rc = ssh_connect(session);
+ assert_ssh_return_code(session, rc);
+
+ ssh_set_blocking(session, 0);
+ do {
+ rc = ssh_userauth_none(session, NULL);
+ } while (rc == SSH_AUTH_AGAIN);
+
+ /* 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);
+
+ /* set unreasonable large minimum key size to trigger the condition */
+ rc = ssh_options_set(session, SSH_OPTIONS_RSA_MIN_SIZE, &limit); /* larger than the test key */
+ assert_ssh_return_code(session, rc);
+
+ /* Import the RSA private key */
+ rc = ssh_pki_import_privkey_file(bob_ssh_key, NULL, NULL, NULL, &privkey);
+ assert_int_equal(rc, SSH_OK);
+
+ do {
+ rc = ssh_userauth_publickey(session, NULL, privkey);
+ } while (rc == SSH_AUTH_AGAIN);
+ assert_int_equal(rc, SSH_AUTH_DENIED);
+
+ /* revert to default values which should work also in FIPS mode */
+ limit = 0;
+ rc = ssh_options_set(session, SSH_OPTIONS_RSA_MIN_SIZE, &limit);
+ assert_ssh_return_code(session, rc);
+
+ do {
+ rc = ssh_userauth_publickey(session, NULL, privkey);
+ } while (rc == SSH_AUTH_AGAIN);
+ assert_int_equal(rc, SSH_AUTH_SUCCESS);
+
+ SSH_KEY_FREE(privkey);
}
int torture_run_tests(void) {
@@ -903,21 +1256,45 @@ int torture_run_tests(void) {
cmocka_unit_test_setup_teardown(torture_auth_none_nonblocking,
session_setup,
session_teardown),
- cmocka_unit_test_setup_teardown(torture_auth_password,
+ cmocka_unit_test_setup_teardown(torture_auth_none_max_tries,
+ session_setup,
+ session_teardown),
+ cmocka_unit_test_setup_teardown(torture_auth_password_good,
session_setup,
session_teardown),
- cmocka_unit_test_setup_teardown(torture_auth_password_nonblocking,
+ cmocka_unit_test_setup_teardown(torture_auth_password_nonblocking_good,
session_setup,
session_teardown),
- cmocka_unit_test_setup_teardown(torture_auth_kbdint,
+ cmocka_unit_test_setup_teardown(torture_auth_password_bad,
session_setup,
session_teardown),
- cmocka_unit_test_setup_teardown(torture_auth_kbdint_nonblocking,
+ cmocka_unit_test_setup_teardown(torture_auth_password_nonblocking_bad,
session_setup,
session_teardown),
+ cmocka_unit_test_setup_teardown(torture_auth_kbdint_good,
+ session_setup,
+ session_teardown),
+ cmocka_unit_test_setup_teardown(torture_auth_kbdint_nonblocking_good,
+ session_setup,
+ session_teardown),
+ cmocka_unit_test_setup_teardown(torture_auth_kbdint_bad,
+ session_setup,
+ session_teardown),
+ cmocka_unit_test_setup_teardown(torture_auth_kbdint_nonblocking_bad,
+ session_setup,
+ session_teardown),
+ cmocka_unit_test_setup_teardown(torture_auth_pubkey,
+ pubkey_setup,
+ session_teardown),
+ cmocka_unit_test_setup_teardown(torture_auth_pubkey_nonblocking,
+ pubkey_setup,
+ session_teardown),
cmocka_unit_test_setup_teardown(torture_auth_autopubkey,
pubkey_setup,
session_teardown),
+ cmocka_unit_test_setup_teardown(torture_auth_autopubkey_protected,
+ pubkey_setup,
+ session_teardown),
cmocka_unit_test_setup_teardown(torture_auth_autopubkey_nonblocking,
pubkey_setup,
session_teardown),
@@ -927,14 +1304,11 @@ int torture_run_tests(void) {
cmocka_unit_test_setup_teardown(torture_auth_agent_nonblocking,
agent_setup,
agent_teardown),
- cmocka_unit_test_setup_teardown(torture_auth_cert,
- pubkey_setup,
- session_teardown),
- cmocka_unit_test_setup_teardown(torture_auth_agent_cert,
- agent_cert_setup,
+ cmocka_unit_test_setup_teardown(torture_auth_agent_identities_only,
+ agent_setup,
agent_teardown),
- cmocka_unit_test_setup_teardown(torture_auth_agent_cert_nonblocking,
- agent_cert_setup,
+ cmocka_unit_test_setup_teardown(torture_auth_agent_identities_only_protected,
+ agent_setup,
agent_teardown),
cmocka_unit_test_setup_teardown(torture_auth_pubkey_types,
pubkey_setup,
@@ -954,6 +1328,12 @@ int torture_run_tests(void) {
cmocka_unit_test_setup_teardown(torture_auth_pubkey_types_ed25519_nonblocking,
pubkey_setup,
session_teardown),
+ cmocka_unit_test_setup_teardown(torture_auth_pubkey_rsa_key_size,
+ pubkey_setup,
+ session_teardown),
+ cmocka_unit_test_setup_teardown(torture_auth_pubkey_rsa_key_size_nonblocking,
+ pubkey_setup,
+ session_teardown),
};
ssh_init();