static void torture_knownhosts_other(void **state) { struct torture_state *s = *state; ssh_session session = s->ssh.session; char known_hosts_file[1024] = {0}; enum ssh_known_hosts_e found; FILE *file = NULL; int rc; snprintf(known_hosts_file, sizeof(known_hosts_file), "%s/%s", s->socket_dir, TORTURE_KNOWN_HOSTS_FILE); rc = ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, known_hosts_file); assert_ssh_return_code(session, rc); rc = ssh_options_set(session, SSH_OPTIONS_HOSTKEYS, "ssh-ed25519"); assert_ssh_return_code(session, rc); file = fopen(known_hosts_file, "w"); assert_non_null(file); fprintf(file, "127.0.0.10 %s\n", torture_get_testkey_pub(SSH_KEYTYPE_RSA)); fclose(file); rc = ssh_connect(session); assert_ssh_return_code(session, rc); found = ssh_session_is_known_server(session); assert_int_equal(found, SSH_KNOWN_HOSTS_OTHER); }
static int session_setup(void **state) { struct torture_state *s = *state; int verbosity = torture_libssh_verbosity(); struct passwd *pwd; 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); rc = ssh_options_set(s->ssh.session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity); assert_ssh_return_code(s->ssh.session, rc); rc = ssh_options_set(s->ssh.session, SSH_OPTIONS_HOST, TORTURE_SSH_SERVER); assert_ssh_return_code(s->ssh.session, rc); rc = ssh_options_set(s->ssh.session, SSH_OPTIONS_USER, TORTURE_SSH_USER_ALICE); assert_ssh_return_code(s->ssh.session, rc); return 0; }
static void torture_knownhosts_unknown(void **state) { struct torture_state *s = *state; ssh_session session = s->ssh.session; char known_hosts_file[1024] = {0}; enum ssh_known_hosts_e found; int rc; snprintf(known_hosts_file, sizeof(known_hosts_file), "%s/%s", s->socket_dir, TORTURE_KNOWN_HOSTS_FILE); rc = ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, known_hosts_file); assert_ssh_return_code(session, rc); rc = ssh_options_set(session, SSH_OPTIONS_HOSTKEYS, "ssh-ed25519"); assert_ssh_return_code(session, rc); rc = ssh_connect(session); assert_ssh_return_code(session, rc); found = ssh_session_is_known_server(session); assert_int_equal(found, SSH_KNOWN_HOSTS_UNKNOWN); rc = ssh_session_update_known_hosts(session); assert_ssh_return_code(session, rc); ssh_disconnect(session); ssh_free(session); /* connect again and check host key */ session = ssh_new(); assert_non_null(session); s->ssh.session = session; rc = ssh_options_set(s->ssh.session, SSH_OPTIONS_HOST, TORTURE_SSH_SERVER); assert_ssh_return_code(s->ssh.session, rc); rc = ssh_options_set(s->ssh.session, SSH_OPTIONS_USER, TORTURE_SSH_USER_ALICE); assert_ssh_return_code(s->ssh.session, rc); rc = ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, known_hosts_file); assert_ssh_return_code(session, rc); rc = ssh_connect(session); assert_ssh_return_code(session, rc); /* ssh-rsa is the default but libssh should try ssh-ed25519 instead */ found = ssh_session_is_known_server(session); assert_int_equal(found, SSH_KNOWN_HOSTS_OK); /* session will be freed by session_teardown() */ }
static int session_setup(void **state) { struct torture_state *s = *state; int verbosity = torture_libssh_verbosity(); 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); return 0; }
static void torture_knownhosts_write_and_verify(void **state) { struct torture_state *s = *state; ssh_session session = s->ssh.session; enum ssh_known_hosts_e found; int rc; rc = ssh_connect(session); assert_ssh_return_code(session, rc); rc = ssh_session_update_known_hosts(session); assert_ssh_return_code(session, rc); found = ssh_session_is_known_server(session); assert_int_equal(found, SSH_KNOWN_HOSTS_OK); }
static void torture_auth_pubkey_types_ed25519_nonblocking(void **state) { struct torture_state *s = *state; ssh_session session = s->ssh.session; int rc; 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); /* Enable only DSA keys -- authentication should fail */ rc = ssh_options_set(session, SSH_OPTIONS_PUBLICKEY_ACCEPTED_TYPES, "ssh-dss"); assert_ssh_return_code(session, rc); do { rc = ssh_userauth_publickey_auto(session, NULL, NULL); } while (rc == SSH_AUTH_AGAIN); assert_int_equal(rc, SSH_AUTH_DENIED); /* Verify we can use also ED25519 key to authenticate */ rc = ssh_options_set(session, SSH_OPTIONS_PUBLICKEY_ACCEPTED_TYPES, "ssh-ed25519"); assert_ssh_return_code(session, rc); do { rc = ssh_userauth_publickey_auto(session, NULL, NULL); } while (rc == SSH_AUTH_AGAIN); assert_int_equal(rc, SSH_AUTH_SUCCESS); }
static void torture_auth_pubkey_types_nonblocking(void **state) { struct torture_state *s = *state; ssh_session session = s->ssh.session; int rc; 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); /* Disable RSA key types for authentication */ rc = ssh_options_set(session, SSH_OPTIONS_PUBLICKEY_ACCEPTED_TYPES, "ssh-dss"); assert_ssh_return_code(session, rc); do { rc = ssh_userauth_publickey_auto(session, NULL, NULL); } while (rc == SSH_AUTH_AGAIN); assert_int_equal(rc, SSH_AUTH_DENIED); /* Now enable it and retry */ rc = ssh_options_set(session, SSH_OPTIONS_PUBLICKEY_ACCEPTED_TYPES, "rsa-sha2-512,ssh-rsa"); assert_ssh_return_code(session, rc); do { rc = ssh_userauth_publickey_auto(session, NULL, NULL); } while (rc == SSH_AUTH_AGAIN); assert_int_equal(rc, SSH_AUTH_SUCCESS); }
static void torture_hostkey_dss(void **state) { struct torture_state *s = *state; ssh_session session = s->ssh.session; char rsa[] = "ssh-dss"; int rc; rc = ssh_options_set(session, SSH_OPTIONS_HOSTKEYS, &rsa); assert_ssh_return_code(session, rc); rc = ssh_connect(session); assert_ssh_return_code(session, rc); ssh_disconnect(session); rc = ssh_connect(session); assert_ssh_return_code(session, rc); }
static void torture_hostkey_ecdsa(void **state) { struct torture_state *s = *state; ssh_session session = s->ssh.session; char ecdsa[] = "ecdsa-sha2-nistp521"; int rc; rc = ssh_options_set(session, SSH_OPTIONS_HOSTKEYS, &ecdsa); assert_ssh_return_code(session, rc); rc = ssh_connect(session); assert_ssh_return_code(session, rc); ssh_disconnect(session); rc = ssh_connect(session); assert_ssh_return_code(session, rc); }
static void torture_request_env(void **state) { struct torture_state *s = *state; ssh_session session = s->ssh.session; ssh_channel c; char buffer[4096] = {0}; int nbytes; int rc; int lang_found = 0; c = ssh_channel_new(session); assert_non_null(c); rc = ssh_channel_open_session(c); assert_ssh_return_code(session, rc); rc = ssh_channel_request_env(c, "LC_LIBSSH", "LIBSSH_EXPORTED_VARIABLE"); assert_ssh_return_code(session, rc); rc = ssh_channel_request_exec(c, "echo $LC_LIBSSH"); assert_ssh_return_code(session, rc); nbytes = ssh_channel_read(c, buffer, sizeof(buffer) - 1, 0); printf("nbytes=%d\n", nbytes); while (nbytes > 0) { #if 1 rc = fwrite(buffer, 1, nbytes, stdout); assert_int_equal(rc, nbytes); #endif buffer[nbytes]='\0'; if (strstr(buffer, "LIBSSH_EXPORTED_VARIABLE")) { lang_found = 1; break; } nbytes = ssh_channel_read(c, buffer, sizeof(buffer), 0); } assert_int_equal(lang_found, 1); ssh_channel_close(c); }
static void torture_knownhosts_export(void **state) { struct torture_state *s = *state; ssh_session session = s->ssh.session; char *entry = NULL; char *p = NULL; int rc; rc = ssh_connect(session); assert_ssh_return_code(session, rc); rc = ssh_session_export_known_hosts_entry(session, &entry); assert_ssh_return_code(session, rc); p = strstr(entry, "ssh-ed25519"); if (p != NULL) { assert_string_equal(entry, KNOWN_HOST_ENTRY_ED25519); } else { assert_string_equal(entry, KNOWN_HOST_ENTRY_ECDSA); } SAFE_FREE(entry); }
static void torture_auth_pubkey_types_ecdsa(void **state) { struct torture_state *s = *state; ssh_session session = s->ssh.session; int rc; 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); /* We have only the 256b key -- whitelisting only larger should fail */ rc = ssh_options_set(session, SSH_OPTIONS_PUBLICKEY_ACCEPTED_TYPES, "ecdsa-sha2-nistp384"); assert_ssh_return_code(session, rc); rc = ssh_userauth_publickey_auto(session, NULL, NULL); assert_int_equal(rc, SSH_AUTH_DENIED); /* Verify we can use also ECDSA keys with their various names */ rc = ssh_options_set(session, SSH_OPTIONS_PUBLICKEY_ACCEPTED_TYPES, "ecdsa-sha2-nistp256"); assert_ssh_return_code(session, rc); rc = ssh_userauth_publickey_auto(session, NULL, NULL); assert_int_equal(rc, SSH_AUTH_SUCCESS); }
static void torture_channel_read_error(void **state) { struct torture_state *s = *state; ssh_session session = s->ssh.session; ssh_channel channel; int rc; int fd; int i; channel = ssh_channel_new(session); assert_non_null(channel); rc = ssh_channel_open_session(channel); assert_ssh_return_code(session, rc); rc = ssh_channel_request_exec(channel, "hexdump -C /dev/urandom"); assert_ssh_return_code(session, rc); /* send crap and for server to send us a disconnect */ fd = ssh_get_fd(session); assert_true(fd > 2); rc = write(fd, "AAAA", 4); assert_int_equal(rc, 4); for (i=0;i<20;++i){ rc = ssh_channel_read(channel,buffer,sizeof(buffer),0); if (rc == SSH_ERROR) break; } #if OPENSSH_VERSION_MAJOR == 6 && OPENSSH_VERSION_MINOR >= 7 /* With openssh 6.7 this doesn't produce and error anymore */ assert_ssh_return_code(session, rc); #else assert_ssh_return_code_equal(session, rc, SSH_ERROR); #endif ssh_channel_free(channel); }
static void torture_knownhosts_conflict(void **state) { struct torture_state *s = *state; ssh_session session = s->ssh.session; char known_hosts_file[1024] = {0}; enum ssh_known_hosts_e found; FILE *file = NULL; int rc; snprintf(known_hosts_file, sizeof(known_hosts_file), "%s/%s", s->socket_dir, TORTURE_KNOWN_HOSTS_FILE); file = fopen(known_hosts_file, "w"); assert_non_null(file); fprintf(file, "127.0.0.10 %s %s\n", "ssh-ed25519", BAD_ED25519); fclose(file); rc = ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, known_hosts_file); assert_ssh_return_code(session, rc); rc = ssh_options_set(session, SSH_OPTIONS_HOSTKEYS, "ssh-ed25519"); assert_ssh_return_code(session, rc); rc = ssh_connect(session); assert_ssh_return_code(session, rc); found = ssh_session_is_known_server(session); assert_int_equal(found, SSH_KNOWN_HOSTS_CHANGED); rc = ssh_session_update_known_hosts(session); assert_ssh_return_code(session, rc); ssh_disconnect(session); ssh_free(session); /* connect again and check host key */ session = ssh_new(); assert_non_null(session); s->ssh.session = session; rc = ssh_options_set(session, SSH_OPTIONS_HOST, TORTURE_SSH_SERVER); assert_ssh_return_code(session, rc); rc = ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, known_hosts_file); assert_ssh_return_code(session, rc); rc = ssh_options_set(session, SSH_OPTIONS_HOSTKEYS, "ssh-ed25519"); assert_ssh_return_code(session, rc); rc = ssh_connect(session); assert_ssh_return_code(session, rc); found = ssh_session_is_known_server(session); assert_int_equal(found, SSH_KNOWN_HOSTS_OK); /* session will be freed by session_teardown() */ }
static void torture_knownhosts_precheck(void **state) { struct torture_state *s = *state; ssh_session session = s->ssh.session; struct ssh_list *algo_list = NULL; struct ssh_iterator *it = NULL; size_t algo_count; const char *algo = NULL; char known_hosts_file[1024] = {0}; FILE *file; int rc; snprintf(known_hosts_file, sizeof(known_hosts_file), "%s/%s", s->socket_dir, TORTURE_KNOWN_HOSTS_FILE); file = fopen(known_hosts_file, "w"); assert_non_null(file); fprintf(file, "127.0.0.10 %s\n", torture_get_testkey_pub(SSH_KEYTYPE_RSA)); fprintf(file, "127.0.0.10 %s\n", torture_get_testkey_pub(SSH_KEYTYPE_ED25519)); fprintf(file, "127.0.0.10 %s\n", torture_get_testkey_pub(SSH_KEYTYPE_ECDSA_P521)); fclose(file); rc = ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, known_hosts_file); assert_ssh_return_code(session, rc); algo_list = ssh_known_hosts_get_algorithms(session); assert_non_null(algo_list); algo_count = ssh_list_count(algo_list); assert_int_equal(algo_count, 3); it = ssh_list_get_iterator(algo_list); assert_non_null(it); algo = ssh_iterator_value(const char *, it); assert_string_equal(algo, "ssh-rsa"); ssh_list_remove(algo_list, it); it = ssh_list_get_iterator(algo_list); assert_non_null(it); algo = ssh_iterator_value(const char *, it); assert_string_equal(algo, "ssh-ed25519"); ssh_list_remove(algo_list, it); it = ssh_list_get_iterator(algo_list); assert_non_null(it); algo = ssh_iterator_value(const char *, it); assert_string_equal(algo, "ecdsa-sha2-nistp521"); ssh_list_free(algo_list); }