Ejemplo n.º 1
0
/**
 * cockpit_transport_parse_command:
 * @payload: command JSON payload to parse
 * @command: a location to return the command
 * @channel: location to return the channel
 * @options: location to return the options
 *
 * Parse a command and return various values from the
 * command. The @options value is transfered with ownership,
 * so you should free it after done. @command and @channel are owned by
 * @options. @channel will be NULL for a missing channel.
 *
 * On failure, message has already been printed.
 *
 * Returns: whether command parsed or not.
 */
gboolean
cockpit_transport_parse_command (GBytes *payload,
                                 const gchar **command,
                                 const gchar **channel,
                                 JsonObject **options)
{
  GError *error = NULL;
  gboolean ret = FALSE;
  JsonObject *object;
  gboolean valid;

  object = cockpit_json_parse_bytes (payload, &error);
  if (!object)
    {
      g_warning ("Received unparseable control message: %s", error->message);
      g_error_free (error);
      goto out;
    }

  /* Parse out the command */
  if (command)
    {
      if (!cockpit_json_get_string (object, "command", NULL, command) ||
          *command == NULL || g_str_equal (*command, ""))
        {
          g_warning ("Received invalid control message: invalid or missing command");
          goto out;
        }
    }

  /* Parse out the channel */
  valid = cockpit_json_get_string (object, "channel", NULL, channel);
  if (valid && *channel)
    {
      valid = (!g_str_equal ("", *channel) &&
               strcspn (*channel, "\n") == strlen (*channel));
    }

  if (!valid)
    {
      g_warning ("Received invalid control message: invalid channel");
      goto out;
    }

  *options = json_object_ref (object);
  ret = TRUE;

out:
  if (object)
    json_object_unref (object);
  return ret;
}
Ejemplo n.º 2
0
static JsonObject *
read_package_manifest (const gchar *directory,
                       const gchar *package)
{
  JsonObject *manifest = NULL;
  GError *error = NULL;
  GMappedFile *mapped;
  gchar *filename;
  GBytes *bytes;

  filename = g_build_filename (directory, "manifest.json", NULL);
  mapped = g_mapped_file_new (filename, FALSE, &error);
  if (!mapped)
    {
      if (g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT))
        g_debug ("no manifest found: %s", filename);
      else if (!g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOTDIR))
        g_message ("%s: %s", package, error->message);
      g_clear_error (&error);
    }
  else
    {
     if (!validate_package (package))
       {
         g_warning ("package has invalid name: %s", package);
       }
     else
       {
         bytes = g_mapped_file_get_bytes (mapped);
         manifest = cockpit_json_parse_bytes (bytes, &error);
         g_bytes_unref (bytes);

         if (!manifest)
           {
             g_message ("%s: invalid manifest: %s", package, error->message);
             g_clear_error (&error);
           }
       }

      g_mapped_file_unref (mapped);
    }

  g_free (filename);
  return manifest;
}
Ejemplo n.º 3
0
static gboolean
on_httpstream_recv (CockpitTransport *transport,
                    const gchar *channel,
                    GBytes *payload,
                    CockpitChannelResponse *chesp)
{
  GError *error = NULL;
  JsonObject *object;
  gint64 status;
  const gchar *reason;

  if (!channel || !g_str_equal (channel, chesp->channel))
    return FALSE;

  g_return_val_if_fail (cockpit_web_response_get_state (chesp->response) == COCKPIT_WEB_RESPONSE_READY, FALSE);

  /* First response payload message is meta data, then switch to actual data */
  g_signal_handler_disconnect (chesp->transport, chesp->transport_recv);
  chesp->transport_recv = g_signal_connect (chesp->transport, "recv", G_CALLBACK (on_transport_recv), chesp);

  object = cockpit_json_parse_bytes (payload, &error);
  if (error)
    {
      g_warning ("%s: couldn't parse http-stream1 header payload: %s", chesp->logname, error->message);
      cockpit_web_response_error (chesp->response, 500, NULL, NULL);
      g_error_free (error);
      return TRUE;
    }

  if (parse_httpstream_response (chesp, object, &status, &reason))
    {
      if (!ensure_headers (chesp, status, reason))
        g_return_val_if_reached (FALSE);
    }
  else
    {
      cockpit_web_response_error (chesp->response, 500, NULL, NULL);
    }

  json_object_unref (object);
  return TRUE;
}