static void cockpit_ssh_transport_close (CockpitTransport *transport, const gchar *problem) { CockpitSshTransport *self = COCKPIT_SSH_TRANSPORT (transport); if (self->closed) return; self->closing = TRUE; /* If still connecting and there isn't a problem * don't do anything yet */ if (self->connecting && !problem) return; if (self->pipe) { cockpit_pipe_close (self->pipe, problem); } else if (self->auth_process) { cockpit_ssh_transport_remove_auth_process (self); self->closed = TRUE; cockpit_transport_emit_closed (COCKPIT_TRANSPORT (self), problem); } }
static void emit_string (TestCase *tc, const gchar *channel, const gchar *string) { GBytes *bytes = g_bytes_new (string, strlen (string)); cockpit_transport_emit_recv (COCKPIT_TRANSPORT (tc->transport), channel, bytes); g_bytes_unref (bytes); }
static void on_pipe_close (CockpitPipe *pipe, const gchar *problem, gpointer user_data) { CockpitPipeTransport *self = COCKPIT_PIPE_TRANSPORT (user_data); gboolean is_cockpit; GError *error = NULL; gint status; self->closed = TRUE; /* This function is called by the base class when it is closed */ if (cockpit_pipe_get_pid (pipe, NULL)) { is_cockpit = g_str_equal (self->name, "cockpit-bridge") || g_str_equal (self->name, "cockpit-session"); if (problem == NULL || g_str_equal (problem, "internal-error")) { status = cockpit_pipe_exit_status (pipe); if (WIFSIGNALED (status) && WTERMSIG (status) == SIGTERM) problem = "terminated"; else if (is_cockpit && WIFEXITED (status) && WEXITSTATUS (status) == 127) problem = "no-cockpit"; // cockpit-bridge not installed else if (WIFEXITED (status) && WEXITSTATUS (status) == 255) problem = "terminated"; // failed or got a signal, etc. else if (!g_spawn_check_exit_status (status, &error)) { problem = "internal-error"; if (is_cockpit) g_warning ("%s: bridge program failed: %s", self->name, error->message); else g_debug ("%s: process failed: %s", self->name, error->message); g_error_free (error); } } else if (g_str_equal (problem, "not-found")) { if (is_cockpit) { g_message ("%s: failed to execute bridge: not found", self->name); problem = "no-cockpit"; } else { g_debug ("%s: failed to run: not found", self->name); } } } g_debug ("%s: closed%s%s", self->name, problem ? ": " : "", problem ? problem : ""); cockpit_transport_emit_closed (COCKPIT_TRANSPORT (self), problem); }
static void on_pipe_read (CockpitPipe *pipe, GByteArray *input, gboolean end_of_data, gpointer user_data) { CockpitPipeTransport *self = COCKPIT_PIPE_TRANSPORT (user_data); cockpit_transport_read_from_pipe (COCKPIT_TRANSPORT (self), self->name, pipe, &self->closed, input, end_of_data); }
static void on_pipe_close (CockpitPipe *pipe, const gchar *problem, gpointer user_data) { CockpitInteractTransport *self = COCKPIT_INTERACT_TRANSPORT (user_data); g_debug ("%s: closed%s%s", self->name, problem ? ": " : "", problem ? problem : ""); cockpit_transport_emit_closed (COCKPIT_TRANSPORT (self), problem); }
static void on_pipe_close (CockpitPipe *pipe, const gchar *problem, gpointer user_data) { CockpitPipeTransport *self = COCKPIT_PIPE_TRANSPORT (user_data); GError *error = NULL; gint status; /* This function is called by the base class when it is closed */ if (cockpit_pipe_get_pid (pipe, NULL)) { if (problem == NULL) { status = cockpit_pipe_exit_status (pipe); if (WIFSIGNALED (status) && WTERMSIG (status) == SIGTERM) problem = "terminated"; else if (WIFEXITED (status) && WEXITSTATUS (status) == 5) problem = "not-authorized"; // wrong password else if (WIFEXITED (status) && WEXITSTATUS (status) == 6) problem = "unknown-hostkey"; else if (WIFEXITED (status) && WEXITSTATUS (status) == 127) problem = "no-agent"; // cockpit-agent not installed else if (WIFEXITED (status) && WEXITSTATUS (status) == 255) problem = "terminated"; // ssh failed or got a signal, etc. else if (!g_spawn_check_exit_status (status, &error)) { problem = "internal-error"; g_warning ("%s: agent program failed: %s", self->name, error->message); g_error_free (error); } } else if (g_str_equal (problem, "not-found")) { g_message ("%s: failed to execute agent: not found", self->name); problem = "no-agent"; } } g_debug ("%s: closed%s%s", self->name, problem ? ": " : "", problem ? problem : ""); cockpit_transport_emit_closed (COCKPIT_TRANSPORT (self), problem); }
static void on_pipe_close (CockpitPipe *pipe, const gchar *problem, gpointer user_data) { CockpitSshTransport *self = COCKPIT_SSH_TRANSPORT (user_data); GError *error = NULL; gint status; self->closing = TRUE; self->closed = TRUE; /* This function is called by the base class when it is closed */ if (cockpit_pipe_get_pid (pipe, NULL)) { if (problem == NULL || g_str_equal (problem, "internal-error") || g_str_equal (problem, "terminated")) { status = cockpit_pipe_exit_status (pipe); if (WIFSIGNALED (status) && WTERMSIG (status) == SIGTERM) problem = "terminated"; else if (WIFEXITED (status) && WEXITSTATUS (status) == 127) problem = "no-cockpit"; // cockpit-bridge not installed else if (WIFEXITED (status) && WEXITSTATUS (status) == 255) problem = "terminated"; // failed or got a signal, etc. else if (WIFEXITED (status) && WEXITSTATUS (status) == 254) problem = "disconnected"; // got IO_ERR. else if (!g_spawn_check_exit_status (status, &error)) { if (problem == NULL) problem = "internal-error"; g_warning ("%s: ssh session failed: %s", self->logname, error->message); g_error_free (error); } } } g_debug ("%s: closed%s%s", self->logname, problem ? ": " : "", problem ? problem : ""); cockpit_transport_emit_closed (COCKPIT_TRANSPORT (self), problem); }
static void close_immediately (CockpitSshTransport *self, const gchar *problem) { GSource *source; GThread *thread; if (self->timeout_close) { g_source_remove (self->timeout_close); self->timeout_close = 0; } if (self->closed) return; self->closed = TRUE; if (self->connect_thread) { thread = self->connect_thread; self->connect_thread = NULL; /* This causes thread to fail */ g_atomic_int_set (&self->connecting, 0); close (self->connect_fd); self->connect_fd = -1; g_assert (self->data == NULL); self->data = g_thread_join (thread); } g_assert (self->data != NULL); if (problem == NULL) problem = self->problem; g_object_ref (self); if (!self->result_emitted) { self->result_emitted = TRUE; g_signal_emit_by_name (self, "result", problem); } g_debug ("%s: closing io%s%s", self->logname, problem ? ": " : "", problem ? problem : ""); if (self->io) { source = self->io; self->io = NULL; g_source_destroy (source); g_source_unref (source); } if (self->data->channel && ssh_channel_is_open (self->data->channel)) ssh_channel_close (self->data->channel); ssh_disconnect (self->data->session); cockpit_transport_emit_closed (COCKPIT_TRANSPORT (self), problem); g_object_unref (self); }