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);
}
Beispiel #5
0
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);
}
Beispiel #8
0
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);
}