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; } 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_true(ssh_get_error_code(session) == SSH_REQUEST_DENIED); } rc = ssh_userauth_list(session, NULL); assert_true(rc & SSH_AUTH_METHOD_PUBLICKEY); ssh_set_blocking(session,0); do { rc = ssh_userauth_agent(session, NULL); } while (rc == SSH_AUTH_AGAIN); assert_int_equal(rc, SSH_AUTH_SUCCESS); }
static void torture_auth_autopubkey_nonblocking(void **state) { ssh_session session = *state; char *user = getenv("TORTURE_USER"); int rc; if (user == NULL) { print_message("*** Please set the environment variable TORTURE_USER" " to enable this test!!\n"); return; } rc = ssh_options_set(session, SSH_OPTIONS_USER, user); assert_true(rc == SSH_OK); rc = ssh_connect(session); assert_true(rc == SSH_OK); 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_true(ssh_get_error_code(session) == SSH_REQUEST_DENIED); } rc = ssh_userauth_list(session, NULL); assert_true(rc & SSH_AUTH_METHOD_PUBLICKEY); do { rc = ssh_userauth_publickey_auto(session, NULL, NULL); } while (rc == SSH_AUTH_AGAIN); assert_true(rc == SSH_AUTH_SUCCESS); }
static void torture_auth_password_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_BOB); 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); /* This request should return a SSH_REQUEST_DENIED error */ if (rc == SSH_AUTH_ERROR) { assert_true(ssh_get_error_code(session) == SSH_REQUEST_DENIED); } rc = ssh_userauth_list(session, NULL); assert_true(rc & SSH_AUTH_METHOD_PASSWORD); do { rc = ssh_userauth_password(session, NULL, TORTURE_SSH_USER_BOB_PASSWORD); } while(rc==SSH_AUTH_AGAIN); assert_int_equal(rc, SSH_AUTH_SUCCESS); }
static void torture_auth_none_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_int_equal(rc, SSH_OK); rc = ssh_connect(session); assert_int_equal(rc, SSH_OK); /* This request should return a SSH_REQUEST_DENIED error */ if (rc == SSH_ERROR) { assert_int_equal(ssh_get_error_code(session), SSH_REQUEST_DENIED); } 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); }
static void torture_auth_kbdint_nonblocking(void **state) { ssh_session session = *state; char *user = getenv("TORTURE_USER"); char *password = getenv("TORTURE_PASSWORD"); int rc; if (user == NULL) { print_message("*** Please set the environment variable TORTURE_USER" " to enable this test!!\n"); return; } if (password == NULL) { print_message("*** Please set the environment variable " "TORTURE_PASSWORD to enable this test!!\n"); return; } rc = ssh_options_set(session, SSH_OPTIONS_USER, user); assert_true(rc == SSH_OK); rc = ssh_connect(session); assert_true(rc == SSH_OK); 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_true(ssh_get_error_code(session) == SSH_REQUEST_DENIED); } rc = ssh_userauth_list(session, NULL); assert_true(rc & SSH_AUTH_METHOD_INTERACTIVE); do { rc = ssh_userauth_kbdint(session, NULL, NULL); } while (rc == SSH_AUTH_AGAIN); assert_true(rc == SSH_AUTH_INFO); assert_int_equal(ssh_userauth_kbdint_getnprompts(session), 1); do { rc = ssh_userauth_kbdint_setanswer(session, 0, password); } while (rc == SSH_AUTH_AGAIN); 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) { assert_int_equal(ssh_userauth_kbdint_getnprompts(session), 0); do { rc = ssh_userauth_kbdint(session, NULL, NULL); } while (rc == SSH_AUTH_AGAIN); } assert_true(rc == SSH_AUTH_SUCCESS); }
void clSSH::Connect(int seconds) { m_session = ssh_new(); if(!m_session) { throw clException("ssh_new failed!"); } ssh_set_blocking(m_session, 0); int verbosity = SSH_LOG_NOLOG; ssh_options_set(m_session, SSH_OPTIONS_HOST, m_host.mb_str(wxConvUTF8).data()); ssh_options_set(m_session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity); ssh_options_set(m_session, SSH_OPTIONS_PORT, &m_port); ssh_options_set(m_session, SSH_OPTIONS_USER, GetUsername().mb_str().data()); // Connect the session int retries = seconds * 100; if(retries < 0) { retries = 1; } DoConnectWithRetries(retries); ssh_set_blocking(m_session, 1); }
static void torture_connect_nonblocking(void **state) { struct torture_state *s = *state; ssh_session session = s->ssh.session; int rc; rc = ssh_options_set(session, SSH_OPTIONS_HOST, TORTURE_SSH_SERVER); assert_true(rc == SSH_OK); ssh_set_blocking(session,0); do { rc = ssh_connect(session); assert_true(rc != SSH_ERROR); } while(rc == SSH_AGAIN); assert_true(rc == SSH_OK); }
static void torture_connect_nonblocking(void **state) { ssh_session session = *state; int rc; rc = ssh_options_set(session, SSH_OPTIONS_HOST, HOST); assert_true(rc == SSH_OK); ssh_set_blocking(session,0); do { rc = ssh_connect(session); assert_true(rc != SSH_ERROR); } while(rc == SSH_AGAIN); assert_true(rc == SSH_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_auth_kbdint_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_BOB); 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); /* This request should return a SSH_REQUEST_DENIED error */ if (rc == SSH_ERROR) { assert_true(ssh_get_error_code(session) == SSH_REQUEST_DENIED); } rc = ssh_userauth_list(session, NULL); assert_true(rc & SSH_AUTH_METHOD_INTERACTIVE); do { rc = ssh_userauth_kbdint(session, NULL, NULL); } while (rc == SSH_AUTH_AGAIN); assert_int_equal(rc, SSH_AUTH_INFO); assert_int_equal(ssh_userauth_kbdint_getnprompts(session), 1); do { rc = ssh_userauth_kbdint_setanswer(session, 0, TORTURE_SSH_USER_BOB_PASSWORD); } while (rc == SSH_AUTH_AGAIN); 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) { 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); }
/** * @brief Create a new ssh session. * * @returns A new ssh_session pointer, NULL on error. */ ssh_session ssh_new(void) { ssh_session session; char *id = NULL; int rc; session = malloc(sizeof (struct ssh_session_struct)); if (session == NULL) { return NULL; } ZERO_STRUCTP(session); session->next_crypto = crypto_new(); if (session->next_crypto == NULL) { goto err; } session->socket = ssh_socket_new(session); if (session->socket == NULL) { goto err; } session->out_buffer = ssh_buffer_new(); if (session->out_buffer == NULL) { goto err; } session->in_buffer=ssh_buffer_new(); if (session->in_buffer == NULL) { goto err; } session->alive = 0; session->auth_methods = 0; ssh_set_blocking(session, 1); session->common.log_indent = 0; session->maxchannel = FIRST_CHANNEL; #ifndef _WIN32 session->agent = agent_new(session); if (session->agent == NULL) { goto err; } #endif /* _WIN32 */ /* OPTIONS */ session->opts.StrictHostKeyChecking = 1; session->opts.port = 22; session->opts.fd = -1; session->opts.ssh2 = 1; session->opts.compressionlevel=7; #ifdef WITH_SSH1 session->opts.ssh1 = 1; #else session->opts.ssh1 = 0; #endif session->opts.identity = ssh_list_new(); if (session->opts.identity == NULL) { goto err; } id = strdup("%d/id_rsa"); if (id == NULL) { goto err; } rc = ssh_list_append(session->opts.identity, id); if (rc == SSH_ERROR) { goto err; } id = strdup("%d/id_dsa"); if (id == NULL) { goto err; } rc = ssh_list_append(session->opts.identity, id); if (rc == SSH_ERROR) { goto err; } id = strdup("%d/identity"); if (id == NULL) { goto err; } rc = ssh_list_append(session->opts.identity, id); if (rc == SSH_ERROR) { goto err; } return session; err: free(id); ssh_free(session); return NULL; }
static gboolean cockpit_ssh_source_prepare (GSource *source, gint *timeout) { CockpitSshSource *cs = (CockpitSshSource *)source; CockpitSshTransport *self = cs->transport; GThread *thread; gint status; *timeout = 1; /* Connecting, check if done */ if (G_UNLIKELY (!self->data)) { if (g_atomic_int_get (&self->connecting)) return FALSE; g_object_ref (self); /* Get the result from connecting thread */ thread = self->connect_thread; self->connect_fd = -1; self->connect_thread = NULL; self->data = g_thread_join (thread); g_assert (self->data != NULL); if (!self->result_emitted) { self->result_emitted = TRUE; g_signal_emit_by_name (self, "result", self->data->problem); } if (self->data->problem) { close_immediately (self, self->data->problem); g_object_unref (self); return FALSE; } g_object_unref (self); ssh_event_add_session (self->event, self->data->session); ssh_set_channel_callbacks (self->data->channel, &self->channel_cbs); /* Start watching the fd */ ssh_set_blocking (self->data->session, 0); cs->pfd.fd = ssh_get_fd (self->data->session); g_source_add_poll (source, &cs->pfd); g_debug ("%s: starting io", self->logname); } status = ssh_get_status (self->data->session); /* Short cut this ... we're ready now */ if (self->drain_buffer) return TRUE; /* * Channel completely closed, and output buffers * are empty. We're in a good place to close the * SSH session and thus the transport. */ if (close_maybe (self, status)) return FALSE; cs->pfd.revents = 0; cs->pfd.events = G_IO_IN | G_IO_ERR | G_IO_NVAL | G_IO_HUP; /* libssh has something in its buffer: want to write */ if (status & SSH_WRITE_PENDING) cs->pfd.events |= G_IO_OUT; /* We have something in our queue: want to write */ else if (!g_queue_is_empty (self->queue)) cs->pfd.events |= G_IO_OUT; /* We are closing and need to send eof: want to write */ else if (self->closing && !self->sent_eof) cs->pfd.events |= G_IO_OUT; /* Need to reply to an EOF or close */ if ((self->received_eof && self->sent_eof && !self->sent_close) || (self->received_close && !self->sent_close)) cs->pfd.events |= G_IO_OUT; return cockpit_ssh_source_check (source); }
/** * @brief Create a new ssh session. * * @returns A new ssh_session pointer, NULL on error. */ ssh_session ssh_new(void) { ssh_session session; char *id = NULL; int rc; session = malloc(sizeof (struct ssh_session_struct)); if (session == NULL) { return NULL; } ZERO_STRUCTP(session); session->next_crypto = crypto_new(); if (session->next_crypto == NULL) { goto err; } session->socket = ssh_socket_new(session); if (session->socket == NULL) { goto err; } session->out_buffer = ssh_buffer_new(); if (session->out_buffer == NULL) { goto err; } session->in_buffer=ssh_buffer_new(); if (session->in_buffer == NULL) { goto err; } session->alive = 0; session->auth_methods = 0; ssh_set_blocking(session, 1); session->maxchannel = FIRST_CHANNEL; #ifndef _WIN32 session->agent = ssh_agent_new(session); if (session->agent == NULL) { goto err; } #endif /* _WIN32 */ /* OPTIONS */ session->opts.StrictHostKeyChecking = 1; session->opts.port = 0; session->opts.fd = -1; session->opts.compressionlevel=7; session->opts.nodelay = 0; session->opts.flags = SSH_OPT_FLAG_PASSWORD_AUTH | SSH_OPT_FLAG_PUBKEY_AUTH | SSH_OPT_FLAG_KBDINT_AUTH | SSH_OPT_FLAG_GSSAPI_AUTH; session->opts.identity = ssh_list_new(); if (session->opts.identity == NULL) { goto err; } id = strdup("%d/id_ed25519"); if (id == NULL) { goto err; } rc = ssh_list_append(session->opts.identity, id); if (rc == SSH_ERROR) { goto err; } #ifdef HAVE_ECC id = strdup("%d/id_ecdsa"); if (id == NULL) { goto err; } rc = ssh_list_append(session->opts.identity, id); if (rc == SSH_ERROR) { goto err; } #endif id = strdup("%d/id_rsa"); if (id == NULL) { goto err; } rc = ssh_list_append(session->opts.identity, id); if (rc == SSH_ERROR) { goto err; } #ifdef HAVE_DSA id = strdup("%d/id_dsa"); if (id == NULL) { goto err; } rc = ssh_list_append(session->opts.identity, id); if (rc == SSH_ERROR) { goto err; } #endif return session; err: free(id); ssh_free(session); return NULL; }
static int my_fd_data_function(UNUSED_PARAM(socket_t fd), int revents, void *userdata) { struct event_fd_data_struct *event_fd_data = (struct event_fd_data_struct *)userdata; ssh_channel channel = event_fd_data->channel; ssh_session session; int len, i, wr; char buf[16384]; int blocking; if (channel == NULL) { _ssh_log(SSH_LOG_FUNCTIONS, "=== my_fd_data_function", "channel == NULL!"); return 0; } session = ssh_channel_get_session(channel); if (ssh_channel_is_closed(channel)) { _ssh_log(SSH_LOG_FUNCTIONS, "=== my_fd_data_function", "channel is closed!"); stack_socket_close(session, event_fd_data); return 0; } if (!(revents & POLLIN)) { if (revents & POLLPRI) { _ssh_log(SSH_LOG_PROTOCOL, "=== my_fd_data_function", "poll revents & POLLPRI"); } if (revents & POLLOUT) { _ssh_log(SSH_LOG_PROTOCOL, "=== my_fd_data_function", "poll revents & POLLOUT"); } if (revents & POLLHUP) { _ssh_log(SSH_LOG_PROTOCOL, "=== my_fd_data_function", "poll revents & POLLHUP"); } if (revents & POLLNVAL) { _ssh_log(SSH_LOG_PROTOCOL, "=== my_fd_data_function", "poll revents & POLLNVAL"); } if (revents & POLLERR) { _ssh_log(SSH_LOG_PROTOCOL, "=== my_fd_data_function", "poll revents & POLLERR"); } return 0; } blocking = ssh_is_blocking(session); ssh_set_blocking(session, 0); _ssh_log(SSH_LOG_FUNCTIONS, "=== my_fd_data_function", "Trying to read from tcp socket fd = %d... (Channel %d:%d state=%d)", *event_fd_data->p_fd, channel->local_channel, channel->remote_channel, channel->state); #ifdef _WIN32 struct sockaddr from; int fromlen = sizeof(from); len = recvfrom(*event_fd_data->p_fd, buf, sizeof(buf), 0, &from, &fromlen); #else len = recv(*event_fd_data->p_fd, buf, sizeof(buf), 0); #endif // _WIN32 if (len < 0) { _ssh_log(SSH_LOG_WARNING, "=== my_fd_data_function", "Reading from tcp socket: %s", strerror(errno)); ssh_channel_send_eof(channel); } else if (len > 0) { if (ssh_channel_is_open(channel)) { wr = 0; do { i = ssh_channel_write(channel, buf, len); if (i < 0) { _ssh_log(SSH_LOG_WARNING, "=== my_fd_data_function", "Error writing on the direct-tcpip channel: %d", i); len = wr; break; } wr += i; _ssh_log(SSH_LOG_FUNCTIONS, "=== my_fd_data_function", "channel_write (%d from %d)", wr, len); } while (i > 0 && wr < len); } else { _ssh_log(SSH_LOG_WARNING, "=== my_fd_data_function", "Can't write on closed channel!"); } } else { _ssh_log(SSH_LOG_PROTOCOL, "=== my_fd_data_function", "The destination host has disconnected!"); ssh_channel_close(channel); #ifdef _WIN32 shutdown(*event_fd_data->p_fd, SD_RECEIVE); #else shutdown(*event_fd_data->p_fd, SHUT_RD); #endif // _WIN32 } ssh_set_blocking(session, blocking); return len; }