on_transport_control (CockpitTransport *transport,
                      const char *command,
                      const gchar *channel,
                      JsonObject *options,
                      GBytes *payload,
                      gpointer user_data)
{
  CockpitSession *session = user_data;
  const gchar *problem = NULL;
  const gchar *message = NULL;
  GSimpleAsyncResult *result;
  GError *error = NULL;
  gboolean ret = TRUE;

  if (g_str_equal (command, "init"))
    {
      g_debug ("session initialized");
      g_signal_handler_disconnect (session->transport, session->control_sig);
      g_signal_handler_disconnect (session->transport, session->close_sig);
      session->control_sig = session->close_sig = 0;
      session->initialized = TRUE;

      if (cockpit_json_get_string (options, "problem", NULL, &problem) && problem)
        {
          if (!cockpit_json_get_string (options, "message", NULL, &message))
            message = NULL;
          propagate_problem_to_error (session, options, problem, message, &error);
          if (session->result)
            {
              g_simple_async_result_take_error (session->result, error);
            }
          else
            {
              g_message ("ignoring failure from session process: %s", error->message);
              g_error_free (error);
            }
        }

      ret = FALSE; /* Let this message be handled elsewhere */
    }
  else if (g_str_equal (command, "authorize"))
    {
      const gchar *challenge;

      /* handle x-host-key challenge */
      if (cockpit_json_get_string (options, "challenge", NULL, &challenge) && g_strcmp0 (challenge, "x-host-key") == 0)
        {
          const gchar *cookie;
          g_return_val_if_fail (cockpit_json_get_string (options, "cookie", NULL, &cookie), FALSE);

          /* return a negative answer; we handle unknown hosts interactively, or want to fail on them */
          g_debug ("received x-host-key authorize challenge");
          send_authorize_reply (session->transport, cookie, "");
          return TRUE;
        }

      /* handle login ("*") challenge */
      g_debug ("received authorize challenge");
      if (session->authorize)
        json_object_unref (session->authorize);
      session->authorize = json_object_ref (options);

      if (reply_authorize_challenge (session))
        return TRUE;
    }
  else
    {
      g_message ("unexpected \"%s\" control message from session before \"init\"", command);
      cockpit_transport_close (transport, "protocol-error");
    }

  if (session->result)
    {
      result = session->result;
      session->result = NULL;
      g_simple_async_result_complete (result);
      g_object_unref (result);
    }

  return ret;
}
on_transport_control (CockpitTransport *transport,
                      const char *command,
                      const gchar *channel,
                      JsonObject *options,
                      GBytes *payload,
                      gpointer user_data)
{
  CockpitSession *session = user_data;
  const gchar *problem = NULL;
  const gchar *message = NULL;
  GSimpleAsyncResult *result;
  GError *error = NULL;
  gboolean ret = TRUE;

  if (g_str_equal (command, "init"))
    {
      g_debug ("session initialized");
      g_signal_handler_disconnect (session->transport, session->control_sig);
      g_signal_handler_disconnect (session->transport, session->close_sig);
      session->control_sig = session->close_sig = 0;
      session->initialized = TRUE;

      if (cockpit_json_get_string (options, "problem", NULL, &problem) && problem)
        {
          if (!cockpit_json_get_string (options, "message", NULL, &message))
            message = NULL;
          propagate_problem_to_error (session, options, problem, message, &error);
          if (session->result)
            {
              g_simple_async_result_take_error (session->result, error);
            }
          else
            {
              g_message ("ignoring failure from session process: %s", error->message);
              g_error_free (error);
            }
        }

      ret = FALSE;  
    }
  else if (g_str_equal (command, "authorize"))
    {
      const gchar *challenge;

       
      if (cockpit_json_get_string (options, "challenge", NULL, &challenge) && g_strcmp0 (challenge, "x-host-key") == 0)
        {
          const gchar *cookie;
          g_return_val_if_fail (cockpit_json_get_string (options, "cookie", NULL, &cookie), FALSE);

           
          g_debug ("received x-host-key authorize challenge");
          send_authorize_reply (session->transport, cookie, "");
          return TRUE;
        }

       
      g_debug ("received authorize challenge");
      if (session->authorize)
        json_object_unref (session->authorize);
      session->authorize = json_object_ref (options);

      if (reply_authorize_challenge (session))
        return TRUE;
    }
  else
    {
      g_message ("unexpected \"%s\" control message from session before \"init\"", command);
      cockpit_transport_close (transport, "protocol-error");
    }

  if (session->result)
    {
      result = session->result;
      session->result = NULL;
      g_simple_async_result_complete (result);
      g_object_unref (result);
    }

  return ret;
}