コード例 #1
0
static void
on_web_socket_message (WebSocketConnection *connection,
                       WebSocketDataType type,
                       GBytes *message,
                       CockpitWebService *self)
{
  CockpitSocket *socket;
  GBytes *payload;
  gchar *channel;

  socket = cockpit_socket_lookup_by_connection (&self->sockets, connection);
  g_return_if_fail (socket != NULL);

  payload = cockpit_transport_parse_frame (message, &channel);
  if (!payload)
    return;

  /* A control channel command */
  if (!channel)
    {
      dispatch_inbound_command (self, socket, payload);
    }

  /* An actual payload message */
  else if (!self->closing)
    {
      if (!self->sent_done)
        cockpit_transport_send (self->transport, channel, payload);
    }

  g_free (channel);
  g_bytes_unref (payload);
}
コード例 #2
0
ファイル: cockpitpipetransport.c プロジェクト: schvin/cockpit
static void
on_pipe_read (CockpitPipe *pipe,
              GByteArray *input,
              gboolean end_of_data,
              gpointer user_data)
{
  CockpitPipeTransport *self = COCKPIT_PIPE_TRANSPORT (user_data);
  GBytes *message;
  GBytes *payload;
  gchar *channel;
  guint32 size;

  for (;;)
    {
      if (input->len < sizeof (size))
        {
          if (!end_of_data)
            g_debug ("%s: want more data", self->name);
          break;
        }

      memcpy (&size, input->data, sizeof (size));
      size = GUINT32_FROM_BE (size);
      if (input->len < size + sizeof (size))
        {
          g_debug ("%s: want more data", self->name);
          break;
        }

      message = cockpit_pipe_consume (input, sizeof (size), size);
      payload = cockpit_transport_parse_frame (message, &channel);
      if (payload)
        {
          g_debug ("%s: received a %d byte payload", self->name, (int)size);
          cockpit_transport_emit_recv ((CockpitTransport *)self, channel, payload);
          g_bytes_unref (payload);
          g_free (channel);
        }
      g_bytes_unref (message);
    }

  if (end_of_data)
    {
      /* Received a partial message */
      if (input->len > 0)
        {
          g_warning ("%s: received truncated %d byte frame", self->name, input->len);
          cockpit_pipe_close (pipe, "internal-error");
        }
    }
}
コード例 #3
0
ファイル: cockpitsshtransport.c プロジェクト: leospol/cockpit
static void
drain_buffer (CockpitSshTransport *self)
{
  GBytes *message;
  GBytes *payload;
  gchar *channel;
  guint32 size;

  for (;;)
    {
      if (self->buffer->len < sizeof (size))
        {
          if (!self->received_eof)
            g_debug ("%s: want len have %d", self->logname, (int)self->buffer->len);
          break;
        }

      memcpy (&size, self->buffer->data, sizeof (size));
      size = GUINT32_FROM_BE (size);
      if (self->buffer->len < size + sizeof (size))
        {
          g_debug ("%s: want %d have %d", self->logname,
                   (int)(size + sizeof (size)), (int)self->buffer->len);
          break;
        }

      message = cockpit_pipe_consume (self->buffer, sizeof (size), size, 0);
      payload = cockpit_transport_parse_frame (message, &channel);
      if (payload)
        {
          g_debug ("%s: received a %d byte payload", self->logname, (int)g_bytes_get_size (payload));
          cockpit_transport_emit_recv ((CockpitTransport *)self, channel, payload);
          g_bytes_unref (payload);
          g_free (channel);
        }
      g_bytes_unref (message);
    }

  if (self->received_eof)
    {
      /* Received a partial message */
      if (self->buffer->len > 0)
        {
          g_warning ("%s: received truncated %d byte frame", self->logname, (int)self->buffer->len);
          close_immediately (self, "internal-error");
        }
    }
}
コード例 #4
0
ファイル: askpass.c プロジェクト: andreasn/cockpit
static JsonObject *
read_control_message (int fd)
{
  JsonObject *options = NULL;
  GBytes *payload = NULL;
  GBytes *bytes = NULL;
  gchar *channel = NULL;
  guchar *data = NULL;
  gssize length = 0;

  length = cockpit_frame_read (fd, &data);
  if (length < 0)
    {
      g_message ("couldn't read askpass authorize message: %s", g_strerror (errno));
      length = 0;
    }
  else if (length > 0)
    {
      /* This could have a password, so clear it when freeing */
      bytes = g_bytes_new_with_free_func (data, length, byte_array_clear_and_free,
                                          g_byte_array_new_take (data, length));
      payload = cockpit_transport_parse_frame (bytes, &channel);
      data = NULL;
    }

  if (payload == NULL)
    {
      if (length > 0)
        g_message ("askpass did not receive valid message");
    }
  else if (channel != NULL)
    {
      g_message ("askpass did not receive a control message");
    }
  else if (!cockpit_transport_parse_command (payload, NULL, NULL, &options))
    {
      g_message ("askpass did not receive a valid control message");
    }

  g_free (channel);

  if (bytes)
    g_bytes_unref (bytes);
  if (payload)
    g_bytes_unref (payload);
  free (data);
  return options;
}
コード例 #5
0
static void
on_pipe_read (CockpitPipe *pipe,
              GByteArray *input,
              gboolean end_of_data,
              gpointer user_data)
{
  CockpitInteractTransport *self = COCKPIT_INTERACT_TRANSPORT (user_data);
  GBytes *message;
  GBytes *payload;
  gchar *channel;
  guint8 *pos;
  guint32 size;

  for (;;)
    {
      pos = NULL;
      if (input->len > 0)
        pos = (guint8 *)g_strstr_len ((gchar *)input->data, input->len, self->delimiter);
      if (!pos)
        {
          if (!end_of_data)
            g_debug ("%s: want more data", self->name);
          break;
        }

      size = pos - input->data;
      message = cockpit_pipe_consume (input, 0, size, self->delimiter_len);

      payload = cockpit_transport_parse_frame (message, &channel);
      if (payload)
        {
          g_debug ("%s: received a %d byte payload", self->name, (int)size);
          cockpit_transport_emit_recv ((CockpitTransport *)self, channel, payload);
          g_bytes_unref (payload);
          g_free (channel);
        }
      g_bytes_unref (message);
    }
}
コード例 #6
0
/**
 * cockpit_transport_read_from_pipe:
 *
 * Meant to be used in a "read" handler for a #CockpitPipe
 * Closed is pointer to a boolean value that may be updated
 * during the read and parse loop.
 */
void
cockpit_transport_read_from_pipe (CockpitTransport *self,
                                  const gchar *logname,
                                  CockpitPipe *pipe,
                                  gboolean *closed,
                                  GByteArray *input,
                                  gboolean end_of_data)
{
  GBytes *message;
  GBytes *payload;
  gchar *channel;
  guint32 i, size;
  gchar *data;

  /* This may be updated during the loop. */
  g_assert (closed != NULL);
  g_object_ref (self);

  while (!*closed)
    {
      size = 0;
      data = (gchar *)input->data;
      for (i = 0; i < input->len; i++)
        {
          /* Check invalid characters, prevent integer overflow, limit max length */
          if (i > 7 || data[i] < '0' || data[i] > '9')
            break;
          size *= 10;
          size += data[i] - '0';
        }

      if (i == input->len)
        {
          if (!end_of_data)
            g_debug ("%s: want more data", logname);
          break;
        }

      if (data[i] != '\n')
        {
          g_warning ("%s: incorrect protocol: received invalid length prefix", logname);
          cockpit_pipe_close (pipe, "protocol-error");
          break;
        }

      if (input->len < i + 1 + size)
        {
          g_debug ("%s: want more data 2", logname);
          break;
        }

      message = cockpit_pipe_consume (input, i + 1, size, 0);
      payload = cockpit_transport_parse_frame (message, &channel);
      if (payload)
        {
          g_debug ("%s: received a %d byte payload", logname, (int)size);
          cockpit_transport_emit_recv (self, channel, payload);
          g_bytes_unref (payload);
          g_free (channel);
        }
      g_bytes_unref (message);
    }

  if (end_of_data)
    {
      /* Received a partial message */
      if (input->len > 0)
        {
          g_debug ("%s: received truncated %d byte frame", logname, input->len);
          cockpit_pipe_close (pipe, "disconnected");
        }
    }

  g_object_unref (self);
}
コード例 #7
0
ファイル: cockpitpipetransport.c プロジェクト: AmartC/cockpit
static void
on_pipe_read (CockpitPipe *pipe,
              GByteArray *input,
              gboolean end_of_data,
              gpointer user_data)
{
  CockpitPipeTransport *self = COCKPIT_PIPE_TRANSPORT (user_data);
  GBytes *message;
  GBytes *payload;
  gchar *channel;
  guint32 i, size;
  gchar *data;

  g_object_ref (self);

  for (;;)
    {
      size = 0;
      data = (gchar *)input->data;
      for (i = 0; i < input->len; i++)
        {
          /* Check invalid characters, prevent integer overflow, limit max length */
          if (i > 7 || data[i] < '0' || data[i] > '9')
            break;
          size *= 10;
          size += data[i] - '0';
        }

      if (i == input->len)
        {
          if (!end_of_data)
            g_debug ("%s: want more data", self->name);
          break;
        }

      if (data[i] != '\n')
        {
          g_warning ("%s: incorrect protocol: received invalid length prefix", self->name);
          cockpit_pipe_close (pipe, "protocol-error");
          break;
        }

      if (input->len < i + 1 + size)
        {
          g_debug ("%s: want more data 2", self->name);
          break;
        }

      message = cockpit_pipe_consume (input, i + 1, size, 0);
      payload = cockpit_transport_parse_frame (message, &channel);
      if (payload)
        {
          g_debug ("%s: received a %d byte payload", self->name, (int)size);
          cockpit_transport_emit_recv ((CockpitTransport *)self, channel, payload);
          g_bytes_unref (payload);
          g_free (channel);
        }
      g_bytes_unref (message);
    }

  if (end_of_data)
    {
      /* Received a partial message */
      if (input->len > 0)
        {
          g_debug ("%s: received truncated %d byte frame", self->name, input->len);
          cockpit_pipe_close (pipe, "disconnected");
        }
    }

  g_object_unref (self);
}