Пример #1
0
static void
on_pipe_read (CockpitPipe *pipe,
              GByteArray *data,
              gboolean end_of_data,
              gpointer user_data)
{
  CockpitTextStream *self = user_data;
  CockpitChannel *channel = user_data;
  GBytes *message;
  GBytes *clean;

  if (data->len || !end_of_data)
    {
      /* When array is reffed, this just clears byte array */
      g_byte_array_ref (data);
      message = g_byte_array_free_to_bytes (data);
      clean = check_utf8_and_force_if_necessary (message);
      cockpit_channel_send (channel, clean);
      g_bytes_unref (message);
      g_bytes_unref (clean);
    }

  /* Close the pipe when writing is done */
  if (end_of_data && self->open)
    {
      g_debug ("%s: end of data, closing pipe", self->name);
      cockpit_pipe_close (pipe, NULL);
    }
}
Пример #2
0
static GBytes *
build_environment (GHashTable *os_release)
{
  /*
   * We don't include entirety of os-release into the
   * environment for the login.html page. There could
   * be unexpected things in here.
   *
   * However since we are displaying branding based on
   * the OS name variant flavor and version, including
   * the corresponding information is not a leak.
   */
  static const gchar *release_fields[] = {
    "NAME", "ID", "PRETTY_NAME", "VARIANT", "VARIANT_ID", "CPE_NAME",
  };

  static const gchar *prefix = "\n    <script>\nvar environment = ";
  static const gchar *suffix = ";\n    </script>";

  GByteArray *buffer;
  GBytes *bytes;
  JsonObject *object;
  const gchar *value;
  gchar *hostname;
  JsonObject *osr;
  gint i;

  object = json_object_new ();
  add_page_to_environment (object);

  hostname = g_malloc0 (HOST_NAME_MAX + 1);
  gethostname (hostname, HOST_NAME_MAX);
  hostname[HOST_NAME_MAX] = '\0';
  json_object_set_string_member (object, "hostname", hostname);
  g_free (hostname);

  if (os_release)
    {
      osr = json_object_new ();
      for (i = 0; i < G_N_ELEMENTS (release_fields); i++)
        {
          value = g_hash_table_lookup (os_release, release_fields[i]);
          if (value)
            json_object_set_string_member (osr, release_fields[i], value);
        }
      json_object_set_object_member (object, "os-release", osr);
    }

  add_oauth_to_environment (object);

  bytes = cockpit_json_write_bytes (object);
  json_object_unref (object);

  buffer = g_bytes_unref_to_array (bytes);
  g_byte_array_prepend (buffer, (const guint8 *)prefix, strlen (prefix));
  g_byte_array_append (buffer, (const guint8 *)suffix, strlen (suffix));
  return g_byte_array_free_to_bytes (buffer);
}
Пример #3
0
static void
byte_array_ensure_gbytes (ByteArrayInstance  *priv)
{
    if (priv->array) {
        priv->bytes = g_byte_array_free_to_bytes(priv->array);
        priv->array = NULL;
    } else {
        g_assert(priv->bytes);
    }
}
Пример #4
0
static void
mock_case_channel_recv (CockpitChannel *channel,
                        GBytes *message)
{
  MockCaseChannel *self = (MockCaseChannel *)channel;
  GByteArray *array = g_bytes_unref_to_array (g_bytes_ref (message));
  GBytes *bytes;
  gsize i;

  for (i = 0; i < array->len; i++)
    array->data[i] = self->function(array->data[i]);

  bytes = g_byte_array_free_to_bytes (array);
  cockpit_channel_send (channel, bytes, FALSE);
  g_bytes_unref (bytes);
}
Пример #5
0
static GBytes *
build_environment (GHashTable *os_release)
{
  static const gchar *prefix = "\n    <script>\nvar environment = ";
  static const gchar *suffix = ";\n    </script>";
  GByteArray *buffer;
  GHashTableIter iter;
  GBytes *bytes;
  JsonObject *object;
  const gchar *title;
  gchar *hostname;
  gpointer key, value;
  JsonObject *osr;

  object = json_object_new ();

  title = cockpit_conf_string ("WebService", "LoginTitle");
  if (title)
    json_object_set_string_member (object, "title", title);

  hostname = g_malloc0 (HOST_NAME_MAX + 1);
  gethostname (hostname, HOST_NAME_MAX);
  hostname[HOST_NAME_MAX] = '\0';
  json_object_set_string_member (object, "hostname", hostname);
  g_free (hostname);

  if (os_release)
    {
      osr = json_object_new ();
      g_hash_table_iter_init (&iter, os_release);
      while (g_hash_table_iter_next (&iter, &key, &value))
        json_object_set_string_member (osr, key, value);
      json_object_set_object_member (object, "os-release", osr);
    }

  add_oauth_to_environment (object);

  bytes = cockpit_json_write_bytes (object);
  json_object_unref (object);

  buffer = g_bytes_unref_to_array (bytes);
  g_byte_array_prepend (buffer, (const guint8 *)prefix, strlen (prefix));
  g_byte_array_append (buffer, (const guint8 *)suffix, strlen (suffix));
  return g_byte_array_free_to_bytes (buffer);
}
Пример #6
0
static void
on_echo_socket_message (WebSocketConnection *self,
                        WebSocketDataType type,
                        GBytes *message,
                        gpointer user_data)
{
  GByteArray *array = g_bytes_unref_to_array (g_bytes_ref (message));
  GBytes *payload;
  guint i;

  /* Capitalize and relay back */
  for (i = 0; i < array->len; i++)
    array->data[i] = g_ascii_toupper (array->data[i]);

  payload = g_byte_array_free_to_bytes (array);
  web_socket_connection_send (self, type, NULL, payload);
  g_bytes_unref (payload);
}
Пример #7
0
/**
 * cockpit_web_response_gunzip:
 * @bytes: the compressed bytes
 * @error: place to put an error
 *
 * Perform gzip decompression on the @bytes.
 *
 * Returns: the uncompressed bytes, caller owns return value.
 */
GBytes *
cockpit_web_response_gunzip (GBytes *bytes,
                             GError **error)
{
  GConverter *converter;
  GConverterResult result;
  const guint8 *in;
  gsize inl, outl, read, written;
  GByteArray *out;

  converter = G_CONVERTER (g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP));

  in = g_bytes_get_data (bytes, &inl);
  out = g_byte_array_new ();

  do
    {
      outl = out->len;
      g_byte_array_set_size (out, outl + inl);

      result = g_converter_convert (converter, in, inl, out->data + outl, inl,
                                    G_CONVERTER_INPUT_AT_END, &read, &written, error);
      if (result == G_CONVERTER_ERROR)
        break;

      g_byte_array_set_size (out, outl + written);
      in += read;
      inl -= read;
    }
  while (result != G_CONVERTER_FINISHED);

  g_object_unref (converter);

  if (result != G_CONVERTER_FINISHED)
    {
      g_byte_array_unref (out);
      return NULL;
    }
  else
    {
      return g_byte_array_free_to_bytes (out);
    }
}
Пример #8
0
/**
 * cockpit_channel_send:
 * @self: a pipe
 * @payload: the message payload to send
 * @trust_is_utf8: set to true if sure data is UTF8
 *
 * Called by implementations to send a message over the transport
 * on the right channel.
 *
 * This message is queued, and sent once the transport can.
 */
void
cockpit_channel_send (CockpitChannel *self,
                      GBytes *payload,
                      gboolean trust_is_utf8)
{
  const guint8 *data;
  gsize length;
  GBytes *send_data = payload;
  GByteArray *combined;

  if (self->priv->buffer_timeout)
    g_source_remove(self->priv->buffer_timeout);
  self->priv->buffer_timeout = 0;

  if (self->priv->out_buffer)
    {
      combined = g_bytes_unref_to_array (self->priv->out_buffer);
      self->priv->out_buffer = NULL;

      data = g_bytes_get_data (payload, &length);
      g_byte_array_append (combined, data, length);
      send_data = g_byte_array_free_to_bytes (combined);

      trust_is_utf8 = FALSE;
    }

  if (!trust_is_utf8 && !self->priv->binary_ok)
    {
      if (cockpit_unicode_has_incomplete_ending (send_data))
        {
          self->priv->out_buffer = g_bytes_ref (send_data);
          self->priv->buffer_timeout = g_timeout_add (500, flush_buffer, self);
        }
    }

  if (!self->priv->buffer_timeout)
    cockpit_channel_actual_send (self, send_data, trust_is_utf8);

  if (send_data != payload)
    g_bytes_unref (send_data);
}