Exemplo n.º 1
0
static void
on_socket_close (WebSocketConnection *connection,
                 CockpitChannelSocket *chock)
{
  const gchar *problem = NULL;
  GBytes *payload;
  gushort code;

  code = web_socket_connection_get_close_code (chock->socket);
  if (code == WEB_SOCKET_CLOSE_NORMAL)
    {
      payload = cockpit_transport_build_control ("command", "done", "channel", chock->channel, NULL);
      cockpit_transport_send (chock->transport, NULL, payload);
      g_bytes_unref (payload);
    }
  else
    {
      problem = web_socket_connection_get_close_data (chock->socket);
      if (problem == NULL)
        problem = "disconnected";
    }

  payload = cockpit_transport_build_control ("command", "close", "channel", chock->channel, "problem", problem, NULL);
  cockpit_transport_send (chock->transport, NULL, payload);
  g_bytes_unref (payload);

  cockpit_channel_socket_close (chock, problem);
}
Exemplo n.º 2
0
static void
on_web_socket_noauth (WebSocketConnection *connection,
                      gpointer data)
{
  GBytes *payload;
  GBytes *prefix;

  g_debug ("closing unauthenticated web socket");

  payload = cockpit_transport_build_control ("command", "init", "problem", "no-session", NULL);
  prefix = g_bytes_new_static ("\n", 1);

  web_socket_connection_send (connection, WEB_SOCKET_DATA_TEXT, prefix, payload);
  web_socket_connection_close (connection, WEB_SOCKET_CLOSE_GOING_AWAY, "no-session");

  g_bytes_unref (prefix);
  g_bytes_unref (payload);
}
Exemplo n.º 3
0
static void
inbound_protocol_error (CockpitWebService *self,
                        WebSocketConnection *connection,
                        const gchar *problem)
{
  GBytes *payload;

  if (problem == NULL)
    problem = "protocol-error";

  if (web_socket_connection_get_ready_state (connection) == WEB_SOCKET_STATE_OPEN)
    {
      payload = cockpit_transport_build_control ("command", "close", "problem", problem, NULL);
      web_socket_connection_send (connection, WEB_SOCKET_DATA_TEXT, self->control_prefix, payload);
      g_bytes_unref (payload);
      web_socket_connection_close (connection, WEB_SOCKET_CLOSE_SERVER_ERROR, problem);
    }
}
Exemplo n.º 4
0
static gboolean
on_ping_time (gpointer user_data)
{
  CockpitWebService *self = user_data;
  WebSocketConnection *connection;
  GHashTableIter iter;
  GBytes *payload;

  payload = cockpit_transport_build_control ("command", "ping", NULL);

  g_hash_table_iter_init (&iter, self->sockets.by_connection);
  while (g_hash_table_iter_next (&iter, (gpointer *)&connection, NULL))
    {
      if (web_socket_connection_get_ready_state (connection) == WEB_SOCKET_STATE_OPEN)
        web_socket_connection_send (connection, WEB_SOCKET_DATA_TEXT, self->control_prefix, payload);
    }

  g_bytes_unref (payload);
  return TRUE;
}
Exemplo n.º 5
0
static gboolean
on_web_socket_closing (WebSocketConnection *connection,
                       CockpitWebService *self)
{
  CockpitSocket *socket;
  GHashTable *snapshot;
  GHashTableIter iter;
  const gchar *channel;
  GBytes *payload;

  g_debug ("web socket closing");

  if (self->sent_done)
    return TRUE;

  /* Close any channels that were opened by this web socket */
  snapshot = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
  socket = cockpit_socket_lookup_by_connection (&self->sockets, connection);
  if (socket)
    {
      g_hash_table_iter_init (&iter, socket->channels);
      while (g_hash_table_iter_next (&iter, (gpointer *)&channel, NULL))
        {
          g_hash_table_add (snapshot, g_strdup (channel));
        }
    }

  g_hash_table_iter_init (&iter, snapshot);
  while (g_hash_table_iter_next (&iter, (gpointer *)&channel, NULL))
    {
      payload = cockpit_transport_build_control ("command", "close",
                                                 "channel", channel,
                                                 "problem", "disconnected",
                                                 NULL);
      cockpit_transport_send (self->transport, NULL, payload);
      g_bytes_unref (payload);
    }
  g_hash_table_destroy (snapshot);

  return TRUE;
}
Exemplo n.º 6
0
static void
send_socket_hints (CockpitWebService *self,
                   const gchar *name,
                   const gchar *value)
{
  CockpitSocket *socket;
  GHashTableIter iter;
  GBytes *payload;

  payload = cockpit_transport_build_control ("command", "hint", name, value, NULL);
  g_hash_table_iter_init (&iter, self->sockets.by_connection);
  while (g_hash_table_iter_next (&iter, NULL, (gpointer *)&socket))
    {
      if (web_socket_connection_get_ready_state (socket->connection) == WEB_SOCKET_STATE_OPEN)
        {
              web_socket_connection_send (socket->connection, WEB_SOCKET_DATA_TEXT,
                                          self->control_prefix, payload);
        }
    }
  g_bytes_unref (payload);
}
Exemplo n.º 7
0
static gboolean
process_transport_authorize (CockpitWebService *self,
                             CockpitTransport *transport,
                             JsonObject *options)
{
  const gchar *cookie = NULL;
  GBytes *payload;
  char *type = NULL;
  char *alloc = NULL;
  const char *response = NULL;
  const gchar *challenge;
  const gchar *password;
  const gchar *host;
  GBytes *data;

  if (!cockpit_json_get_string (options, "challenge", NULL, &challenge) ||
      !cockpit_json_get_string (options, "cookie", NULL, &cookie) ||
      !cockpit_json_get_string (options, "host", NULL, &host))
    {
      g_warning ("received invalid authorize command");
      return FALSE;
    }

  if (!challenge || !cookie)
    {
      g_message ("unsupported or unknown authorize command");
      return FALSE;
    }

  if (!cockpit_authorize_type (challenge, &type))
    {
      g_message ("received invalid authorize challenge command");
    }
  else if (g_str_equal (type, "plain1") ||
           g_str_equal (type, "crypt1") ||
           g_str_equal (type, "basic"))
    {
      data = cockpit_creds_get_password (self->creds);
      if (!data)
        {
          g_debug ("%s: received \"authorize\" %s \"challenge\", but no password", host, type);
        }
      else if (!g_str_equal ("basic", type) && !authorize_check_user (self->creds, challenge))
        {
          g_debug ("received \"authorize\" %s \"challenge\", but for wrong user", type);
        }
      else
        {
          password = g_bytes_get_data (data, NULL);
          if (g_str_equal (type, "crypt1"))
            {
              alloc = cockpit_compat_reply_crypt1 (challenge, password);
              if (alloc)
                response = alloc;
              else
                g_message ("failed to \"authorize\" crypt1 \"challenge\"");
            }
          else if (g_str_equal (type, "basic"))
            {
              response = cockpit_authorize_build_basic (cockpit_creds_get_user (self->creds),
                                                        password);
            }
          else
            {
              response = password;
            }
        }
    }

  /* Tell the frontend that we're reauthorizing */
  if (self->init_received)
    {
      self->credential_requests++;
      send_socket_hints (self, "credential", "request");
    }

  if (cookie && !self->sent_done)
    {
      payload = cockpit_transport_build_control ("command", "authorize",
                                                 "cookie", cookie,
                                                 "response", response ? response : "",
                                                 "host", host,
                                                 NULL);
      cockpit_transport_send (transport, NULL, payload);
      g_bytes_unref (payload);
    }

  free (type);
  free (alloc);
  return TRUE;
}