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
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_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);
}
Beispiel #6
0
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);
}