cockpit_session_launch (CockpitAuth *self,
                        GIOStream *connection,
                        GHashTable *headers,
                        const gchar *type,
                        const gchar *authorization,
                        const gchar *application,
                        GError **error)
{
  CockpitTransport *transport = NULL;
  CockpitSession *session = NULL;
  CockpitCreds *creds = NULL;

  const gchar *host;
  const gchar *action;
  const gchar *command;
  const gchar *section;
  const gchar *program_default;

  gchar **env = g_get_environ ();

  const gchar *argv[] = {
    "command",
    "host",
     NULL,
  };

  host = application_parse_host (application);
  action = type_option (type, "action", "localhost");
  if (g_strcmp0 (action, ACTION_NONE) == 0)
    {
      g_set_error (error, COCKPIT_ERROR, COCKPIT_ERROR_AUTHENTICATION_FAILED,
                   "Authentication disabled");
      goto out;
    }

  /* These are the credentials we'll carry around for this session */
  creds = build_session_credentials (self, connection, headers,
                                     application, type, authorization);

  if (host)
    section = COCKPIT_CONF_SSH_SECTION;
  else if (self->login_loopback && g_strcmp0 (type, "basic") == 0)
    section = COCKPIT_CONF_SSH_SECTION;
  else if (g_strcmp0 (action, ACTION_SSH) == 0)
    section = COCKPIT_CONF_SSH_SECTION;
  else
    section = type;

  if (g_strcmp0 (section, COCKPIT_CONF_SSH_SECTION) == 0)
    {
      if (!host)
        host = type_option (COCKPIT_CONF_SSH_SECTION, "host", "127.0.0.1");

      program_default = cockpit_ws_ssh_program;
    }
  else
    {
      program_default = cockpit_ws_session_program;
    }

  command = type_option (section, "command", program_default);

  if (cockpit_creds_get_rhost (creds))
    {
      env = g_environ_setenv (env, "COCKPIT_REMOTE_PEER",
                              cockpit_creds_get_rhost (creds),
                              TRUE);
    }
  if (g_strcmp0 (g_hash_table_lookup (headers, "X-SSH-Connect-Unknown-Hosts"), "yes") == 0)
    {
      env = g_environ_setenv (env, "COCKPIT_SSH_CONNECT_TO_UNKNOWN_HOSTS",
                              "1",
                              TRUE);
    }

  argv[0] = command;
  argv[1] = host ? host : "localhost";

  transport = session_start_process (argv, (const gchar **)env);
  if (!transport)
    {
      g_set_error (error, COCKPIT_ERROR, COCKPIT_ERROR_FAILED,
                   "Authentication failed to start");
      goto out;
    }

  session = cockpit_session_create (self, argv[0], creds, transport);

  /* How long to wait for the auth process to send some data */
  session->authorize_timeout = timeout_option ("timeout", section, cockpit_ws_auth_process_timeout);

  /* How long to wait for a response from the client to a auth prompt */
  session->client_timeout = timeout_option ("response-timeout", section, cockpit_ws_auth_response_timeout);

out:
  g_strfreev (env);
  if (creds)
    cockpit_creds_unref (creds);
  if (transport)
    g_object_unref (transport);

  return session;
}
cockpit_session_launch (CockpitAuth *self,
                        GIOStream *connection,
                        GHashTable *headers,
                        const gchar *type,
                        const gchar *authorization,
                        const gchar *application,
                        GError **error)
{
  CockpitTransport *transport = NULL;
  CockpitSession *session = NULL;
  CockpitCreds *creds = NULL;

  const gchar *host;
  const gchar *action;
  const gchar *command;
  const gchar *section;
  const gchar *program_default;

  gchar **env = g_get_environ ();

  const gchar *argv[] = {
    "command",
    "host",
     NULL,
  };

  host = application_parse_host (application);
  action = type_option (type, "action", "localhost");
  if (g_strcmp0 (action, ACTION_NONE) == 0)
    {
      g_set_error (error, COCKPIT_ERROR, COCKPIT_ERROR_AUTHENTICATION_FAILED,
                   "Authentication disabled");
      goto out;
    }

   
  creds = build_session_credentials (self, connection, headers,
                                     application, type, authorization);

  if (host)
    section = COCKPIT_CONF_SSH_SECTION;
  else if (self->login_loopback && g_strcmp0 (type, "basic") == 0)
    section = COCKPIT_CONF_SSH_SECTION;
  else if (g_strcmp0 (action, ACTION_SSH) == 0)
    section = COCKPIT_CONF_SSH_SECTION;
  else
    section = type;

  if (g_strcmp0 (section, COCKPIT_CONF_SSH_SECTION) == 0)
    {
      if (!host)
        host = type_option (COCKPIT_CONF_SSH_SECTION, "host", "127.0.0.1");

      program_default = cockpit_ws_ssh_program;
    }
  else
    {
      program_default = cockpit_ws_session_program;
    }

  command = type_option (section, "command", program_default);

  if (cockpit_creds_get_rhost (creds))
    {
      env = g_environ_setenv (env, "COCKPIT_REMOTE_PEER",
                              cockpit_creds_get_rhost (creds),
                              TRUE);
    }
  if (g_strcmp0 (g_hash_table_lookup (headers, "X-SSH-Connect-Unknown-Hosts"), "yes") == 0)
    {
      env = g_environ_setenv (env, "COCKPIT_SSH_CONNECT_TO_UNKNOWN_HOSTS",
                              "1",
                              TRUE);
    }

  argv[0] = command;
  argv[1] = host ? host : "localhost";

  transport = session_start_process (argv, (const gchar **)env);
  if (!transport)
    {
      g_set_error (error, COCKPIT_ERROR, COCKPIT_ERROR_FAILED,
                   "Authentication failed to start");
      goto out;
    }

  session = cockpit_session_create (self, argv[0], creds, transport);

   
  session->authorize_timeout = timeout_option ("timeout", section, cockpit_ws_auth_process_timeout);

   
  session->client_timeout = timeout_option ("response-timeout", section, cockpit_ws_auth_response_timeout);

out:
  g_strfreev (env);
  if (creds)
    cockpit_creds_unref (creds);
  if (transport)
    g_object_unref (transport);

  return session;
}