static void on_pipe_close (CockpitPipe *pipe, const gchar *problem, gpointer user_data) { CockpitTextStream *self = user_data; CockpitChannel *channel = user_data; gint status; gchar *signal; self->open = FALSE; if (cockpit_pipe_get_pid (pipe, NULL)) { status = cockpit_pipe_exit_status (pipe); if (WIFEXITED (status)) cockpit_channel_close_int_option (channel, "exit-status", WEXITSTATUS (status)); else if (WIFSIGNALED (status)) { signal = cockpit_strsignal (WTERMSIG (status)); cockpit_channel_close_option (channel, "exit-signal", signal); g_free (signal); } else if (status) cockpit_channel_close_int_option (channel, "exit-status", -1); } cockpit_channel_close (channel, problem); }
static gboolean check_pipe_exit_status (CockpitPipe *pipe, const gchar *problem, const gchar *prefix) { GError *error = NULL; gint status; if (problem == NULL || g_str_equal (problem, "internal-error")) { status = cockpit_pipe_exit_status (pipe); if (!g_spawn_check_exit_status (status, &error)) { g_message ("%s: %s", prefix, error->message); g_error_free (error); return FALSE; } } else if (problem) { g_message ("%s: %s", prefix, problem); return FALSE; } return TRUE; }
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_helper_close (CockpitPipe *pipe, const gchar *problem, gpointer user_data) { ReauthorizeCaller *caller = user_data; GSimpleAsyncResult *result; gint status; int res; g_warn_if_fail (g_hash_table_steal (caller->self->callers, caller->cookie)); if (caller->result) { result = caller->result; caller->result = NULL; if (problem) { g_message ("cockpit-polkit helper had problem: %s", problem); res = 1; } else { status = cockpit_pipe_exit_status (pipe); if (WIFEXITED (status)) { g_message ("cockpit-polkit helper exited with status: %d", (int)WEXITSTATUS (status)); res = WEXITSTATUS (status); } else if (WIFSIGNALED (status)) { g_message ("cockpit-polkit helper was terminated with signal: %d", (int)WTERMSIG (status)); res = 1; } else { g_message ("cockpit-polkit helper terminated unexpectedly"); res = 1; } } if (res != 0) { g_simple_async_result_set_error (result, POLKIT_ERROR, POLKIT_ERROR_FAILED, "Cockpit polkit agent helper failed"); } g_simple_async_result_complete (result); g_object_unref (result); } g_debug ("closing agent authentication"); caller_free (caller); }
static void on_bridge_done (CockpitPipe *pipe, const gchar *problem, gpointer user_data) { gint status; status = cockpit_pipe_exit_status (pipe); if (WIFEXITED (status)) exit_code = WEXITSTATUS (status); else if (status != 0) exit_code = 1; g_main_loop_quit (loop); }
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 on_other_closed (CockpitTransport *transport, const gchar *problem, gpointer user_data) { CockpitPortal *self = user_data; const gchar **argv; CockpitPipe *pipe; gint status; if (!problem) problem = "disconnected"; if (self->state == PORTAL_OPENING) { pipe = cockpit_pipe_transport_get_pipe (COCKPIT_PIPE_TRANSPORT (self->other)); status = cockpit_pipe_exit_status (pipe); if (status != -1) { argv = current_argv (self); /* These are the problem codes from pkexec. */ if (WIFEXITED (status)) { if (g_str_equal (argv[0], PATH_PKEXEC) && (WEXITSTATUS (status) == 127 || WEXITSTATUS (status) == 126)) problem = "access-denied"; else if (g_str_equal (argv[0], PATH_SUDO) && WEXITSTATUS (status) == 1) problem = "access-denied"; } } g_debug ("other bridge failed: %s", problem); if (self->argvs[self->argvi + 1] != NULL && (g_str_equal (problem, "no-cockpit") || g_str_equal (problem, "not-found") || g_str_equal (problem, "access-denied"))) { self->argvi += 1; disconnect_portal_bridge (self); spawn_portal_bridge (self); return; } if (g_str_equal (problem, "no-cockpit") || g_str_equal (problem, "not-found")) problem = "not-supported"; } else { g_debug ("other bridge closed: %s", problem); } g_free (self->problem); self->problem = g_strdup (problem); if (self->state == PORTAL_OPENING) transition_failed (self); else transition_none (self); }