Esempio n. 1
0
/**
 * dfu_target_get_commands:
 **/
static gboolean
dfu_target_get_commands (DfuTarget *target,
			 GCancellable *cancellable,
			 GError **error)
{
	GBytes *data_in;
	GBytes *data_out;
	guint8 buf[1];

	/* invalid */
	if (!dfu_device_has_dfuse_support (priv->device)) {
		g_set_error_literal (error,
				     DFU_ERROR,
				     DFU_ERROR_NOT_SUPPORTED,
				     "only supported for DfuSe targets");
		return FALSE;
	}

	/* format buffer */
	buf[0] = DFU_CMD_DFUSE_GET_COMMAND;
	data_in = g_bytes_new_static (buf, sizeof(buf));
	if (!dfu_target_download_chunk (target, 0, data_in, cancellable, error))
		return FALSE;

	/* return results */
	data_out = dfu_target_upload_chunk (target, 0, cancellable, error);
	if (data_out == NULL)
		return FALSE;

	// N bytes,
	// each byte is the command code

	// FIXME: parse?
	return TRUE;
}
Esempio n. 2
0
GVariant*
_gba_to_gvariant(GByteArray *gba)
{
	GBytes *gb = g_bytes_new_static (gba->data, gba->len);
	GVariant *gv = _gb_to_gvariant (gb);
	g_bytes_unref (gb);
	return gv;
}
static void
cockpit_web_service_init (CockpitWebService *self)
{
  self->control_prefix = g_bytes_new_static ("\n", 1);
  cockpit_sockets_init (&self->sockets);
  self->ping_timeout = g_timeout_add_seconds (cockpit_ws_ping_interval, on_ping_time, self);
  self->host_by_checksum = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
  self->checksum_by_host = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
}
Esempio n. 4
0
static void
on_auth_process_message (CockpitAuthProcess *auth_process,
                         GBytes *bytes,
                         gpointer user_data)
{
  CockpitSshTransport *self = COCKPIT_SSH_TRANSPORT (user_data);
  JsonObject *json = NULL;
  gchar *response = NULL;
  GError *error = NULL;
  gsize len;
  gboolean prompt_claimed;
  gboolean final = TRUE;
  GBytes *blank = NULL;

  const gchar *user;
  const gchar *error_str;
  const gchar *prompt;
  const gchar *message;
  const gchar *host_key = NULL;
  const gchar *host_fp = NULL;
  JsonObject *auth_result = NULL;
  const gchar *problem = "internal-error";

  len = g_bytes_get_size (bytes);
  response = g_strndup (g_bytes_get_data (bytes, NULL), len);
  json = cockpit_auth_process_parse_result (self->auth_process, response, &error);
  if (json)
    {
      if (!cockpit_json_get_string (json, "error", NULL, &error_str) ||
          !cockpit_json_get_string (json, "message", NULL, &message) ||
          !cockpit_json_get_string (json, "prompt", NULL, &prompt) ||
          !cockpit_json_get_string (json, "user", NULL, &user))
        {
          g_warning ("%s: got invalid authentication json", self->logname);
        }
      else if (error_str)
        {
          problem = error_str;
          g_debug ("%s: got authentication error %s: %s", self->logname, error_str, message);
        }
      else if (prompt)
        {
          final = FALSE;
          problem = NULL;
          // Send the signal, if nothing handles it write a blank response.
          g_signal_emit (self, signals[PROMPT], 0, json, &prompt_claimed);
          if (!prompt_claimed)
            {
              blank = g_bytes_new_static ("", 0);
              cockpit_auth_process_write_auth_bytes (self->auth_process, blank);
              g_bytes_unref (blank);
            }
        }
      else if (user)
Esempio n. 5
0
static void
cockpit_auth_spawn_login_async (CockpitAuth *self,
                                const gchar *application,
                                const gchar *type,
                                gboolean decode_header,
                                GHashTable *headers,
                                const gchar *remote_peer,
                                GAsyncReadyCallback callback,
                                gpointer user_data)
{
  GSimpleAsyncResult *result;
  GBytes *input = NULL;
  AuthData *ad = NULL;
  const gchar *command;

  const gchar *argv[] = {
      "command",
      type,
      remote_peer ? remote_peer : "",
      NULL,
  };

  result = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
                                      cockpit_auth_spawn_login_async);

  command = type_option (type, "command", cockpit_ws_session_program);

  input = cockpit_auth_parse_authorization (headers, decode_header);
  if (!input && !gssapi_not_avail && g_strcmp0 (type, "negotiate") == 0)
    input = g_bytes_new_static ("", 0);

  if (input && application)
    {
      argv[0] = command;
      ad = create_auth_data (self, "localhost", application,
                             type, remote_peer, command, input);
      start_auth_process (self, ad, input, result,
                          cockpit_auth_spawn_login_async, argv);
    }
  else
    {
      g_simple_async_result_set_error (result, COCKPIT_ERROR, COCKPIT_ERROR_AUTHENTICATION_FAILED,
                                       "Authentication required");
      g_simple_async_result_complete_in_idle (result);
    }

  if (input)
    g_bytes_unref (input);

  if (ad)
    auth_data_unref (ad);

  g_object_unref (result);
}
Esempio n. 6
0
static void
handle_raw_data (CockpitWebResponse *response,
                 const gchar *data)
{
    GBytes *block;

    /* For testing code that uses "manifests" return empty manifests for now */
    block = g_bytes_new_static (data, strlen (data));
    cockpit_web_response_content (response, NULL, block, NULL);
    g_bytes_unref (block);
}
Esempio n. 7
0
static void
cockpit_interact_transport_send (CockpitTransport *transport,
                                 const gchar *channel_id,
                                 GBytes *payload)
{
  CockpitInteractTransport *self = COCKPIT_INTERACT_TRANSPORT (transport);
  GBytes *prefix;
  GBytes *suffix;
  GBytes *color;
  gchar *prefix_str;

  if (self->colored)
    {
      color = g_bytes_new_static ("\x1b[1m", 4);
      cockpit_pipe_write (self->pipe, color);
      g_bytes_unref (color);
    }

  prefix_str = g_strdup_printf ("%s\n", channel_id ? channel_id : "");
  prefix = g_bytes_new_take (prefix_str, strlen (prefix_str));
  cockpit_pipe_write (self->pipe, prefix);
  g_bytes_unref (prefix);

  cockpit_pipe_write (self->pipe, payload);

  suffix = g_bytes_new (self->delimiter, self->delimiter_len);
  cockpit_pipe_write (self->pipe, suffix);
  g_bytes_unref (suffix);

  if (self->colored)
    {
      color = g_bytes_new_static ("\x1b[0m", 4);
      cockpit_pipe_write (self->pipe, color);
      g_bytes_unref (color);
    }

  g_debug ("%s: queued %d byte payload", self->name, (int)g_bytes_get_size (payload));
}
Esempio n. 8
0
/**
 * cockpit_web_response_queue:
 * @self: the response
 * @block: the block of data to queue
 *
 * Queue a single block of data on the response. Will be sent
 * during the main loop.
 *
 * See cockpit_web_response_content() for a simple way to
 * avoid queueing individual blocks.
 *
 * If this function returns %FALSE, then the response has failed
 * or has been completed elsewhere. The block was ignored and
 * queuing more blocks doesn't makes sense.
 *
 * After done queuing all your blocks call
 * cockpit_web_response_complete().
*
 * Returns: Whether queuing more blocks makes sense
 */
gboolean
cockpit_web_response_queue (CockpitWebResponse *self,
                            GBytes *block)
{
  gchar *data;
  GBytes *bytes;
  gsize length;

  g_return_val_if_fail (block != NULL, FALSE);
  g_return_val_if_fail (self->complete == FALSE, FALSE);

  if (self->failed)
    {
      g_debug ("%s: ignoring queued block after failure", self->logname);
      return FALSE;
    }

  length = g_bytes_get_size (block);
  g_debug ("%s: queued %d bytes", self->logname, (int)length);

  /*
   * We cannot queue chunks of length zero. Besides being silly, this
   * messes with chunked encoding. The 0 length block means end of
   * response.
   */
  if (length == 0)
    return TRUE;

  if (!self->chunked)
    {
      queue_bytes (self, block);
    }
  else
    {
      /* Required for chunked transfer encoding. */
      data = g_strdup_printf ("%x\r\n", (unsigned int)g_bytes_get_size (block));
      bytes = g_bytes_new_take (data, strlen (data));
      queue_bytes (self, bytes);
      g_bytes_unref (bytes);

      queue_bytes (self, block);

      bytes = g_bytes_new_static ("\r\n", 2);
      queue_bytes (self, bytes);
      g_bytes_unref (bytes);
    }

  return TRUE;
}
/* TODO: Docs. Return value is only valid as long as @txt is. Reference: RFC 6763, §6. */
GHashTable *
_ostree_txt_records_parse (AvahiStringList *txt)
{
  AvahiStringList *l;
  g_autoptr(GHashTable) out = NULL;

  out = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_bytes_unref);

  for (l = txt; l != NULL; l = avahi_string_list_get_next (l))
    {
      const guint8 *txt;
      gsize txt_len;
      const gchar *key;
      const guint8 *value;
      gsize key_len, value_len;
      g_autofree gchar *key_allocated = NULL;
      g_autoptr(GBytes) value_allocated = NULL;

      txt = avahi_string_list_get_text (l);
      txt_len = avahi_string_list_get_size (l);

      if (!parse_txt_record (txt, txt_len, &key, &key_len, &value, &value_len))
        {
          g_debug ("Ignoring invalid TXT record of length %" G_GSIZE_FORMAT,
                   txt_len);
          continue;
        }

      key_allocated = g_ascii_strdown (key, key_len);

      if (g_hash_table_lookup_extended (out, key_allocated, NULL, NULL))
        {
          g_debug ("Ignoring duplicate TXT record ‘%s’", key_allocated);
          continue;
        }

      /* Distinguish between the case where the entire record is the key
       * (value == NULL) and the case where the record is the key + ‘=’ and the
       * value is empty (value != NULL && value_len == 0). */
      if (value != NULL)
        value_allocated = g_bytes_new_static (value, value_len);

      g_hash_table_insert (out, g_steal_pointer (&key_allocated), g_steal_pointer (&value_allocated));
    }

  return g_steal_pointer (&out);
}
Esempio n. 10
0
static gboolean
on_transport_control (CockpitTransport *transport,
                      const char *command,
                      guint channel,
                      JsonObject *options,
                      GBytes *message,
                      gpointer user_data)
{
  CockpitPolkitAgent *self = COCKPIT_POLKIT_AGENT (user_data);
  ReauthorizeCaller *caller;
  const gchar *response;
  const gchar *cookie;
  GBytes *bytes;

  if (!g_str_equal (command, "authorize"))
    return FALSE;

  if (!cockpit_json_get_string (options, "cookie", NULL, &cookie) ||
      !cockpit_json_get_string (options, "response", NULL, &response) ||
      !cookie || !response)
    {
      g_warning ("got an invalid authorize command from cockpit-ws");
      cockpit_transport_close (transport, "protocol-error");
      return TRUE;
    }

  caller = g_hash_table_lookup (self->callers, cookie);
  if (!caller)
    {
      g_debug ("received authorize response for caller that has gone away");
      return TRUE;
    }

  g_debug ("got \"authorize\" response from cockpit-ws, will send to helper: %s", response);

  bytes = g_bytes_new_with_free_func (response, strlen (response),
                                      (GDestroyNotify)json_object_unref,
                                      json_object_ref (options));
  cockpit_pipe_write (caller->helper, bytes);
  g_bytes_unref (bytes);

  bytes = g_bytes_new_static ("\n", 1);
  cockpit_pipe_write (caller->helper, bytes);
  g_bytes_unref (bytes);

  return TRUE;
}
Esempio n. 11
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);
}
Esempio n. 12
0
static void
process_delayed_reply (CockpitRequest *request,
                       const gchar *path,
                       GHashTable *headers)
{
  CockpitWebResponse *response;
  const gchar *host;
  const gchar *body;
  GBytes *bytes;
  gsize length;
  gchar *url;

  g_assert (request->delayed_reply > 299);

  response = cockpit_web_response_new (request->io, NULL, NULL, headers);
  g_signal_connect_data (response, "done", G_CALLBACK (on_web_response_done),
                         g_object_ref (request->web_server), (GClosureNotify)g_object_unref, 0);

  if (request->delayed_reply == 301)
    {
      body = "<html><head><title>Moved</title></head>"
        "<body>Please use TLS</body></html>";
      host = g_hash_table_lookup (headers, "Host");
      url = g_strdup_printf ("https://%s%s",
                             host != NULL ? host : "", path);
      length = strlen (body);
      cockpit_web_response_headers (response, 301, "Moved Permanently", length,
                                    "Content-Type", "text/html",
                                    "Location", url,
                                    NULL);
      g_free (url);
      bytes = g_bytes_new_static (body, length);
      if (cockpit_web_response_queue (response, bytes))
        cockpit_web_response_complete (response);
      g_bytes_unref (bytes);
    }
  else
    {
      cockpit_web_response_error (response, request->delayed_reply, NULL, NULL);
    }

  g_object_unref (response);
}
Esempio n. 13
0
static GBytes *
base64_decode (GBytes *bytes)
{
  gconstpointer data;
  guchar *decoded;
  gsize length;
  gint state = 0;
  guint save = 0;

  data = g_bytes_get_data (bytes, &length);

  if (length == 0)
    return g_bytes_new_static ("", 0);

  /* We can use a smaller limit here, since we know the saved state is 0,
     +1 used to avoid calling g_malloc0(0), and hence returning NULL */
  decoded = g_malloc0 ((length / 4) * 3 + 3);
  length = g_base64_decode_step (data, length, decoded, &state, &save);

  return g_bytes_new_take (decoded, length);
}
static gboolean
_ostree_bootloader_uboot_write_config (OstreeBootloader          *bootloader,
                                  int                    bootversion,
                                  GCancellable          *cancellable,
                                  GError               **error)
{
  OstreeBootloaderUboot *self = OSTREE_BOOTLOADER_UBOOT (bootloader);
  g_autoptr(GFile) new_config_path = NULL;
  g_autofree char *config_contents = NULL;
  g_autofree char *new_config_contents = NULL;
  g_autoptr(GPtrArray) new_lines = NULL;

  /* This should follow the symbolic link to the current bootversion. */
  config_contents = glnx_file_get_contents_utf8_at (AT_FDCWD, gs_file_get_path_cached (self->config_path), NULL,
                                                    cancellable, error);
  if (!config_contents)
    return FALSE;

  new_config_path = ot_gfile_resolve_path_printf (self->sysroot->path, "boot/loader.%d/uEnv.txt",
                                                      bootversion);

  new_lines = g_ptr_array_new_with_free_func (g_free);

  if (!create_config_from_boot_loader_entries (self, bootversion, new_lines,
                                               cancellable, error))
    return FALSE;

  new_config_contents = _ostree_sysroot_join_lines (new_lines);
  {
    g_autoptr(GBytes) new_config_contents_bytes =
      g_bytes_new_static (new_config_contents,
                          strlen (new_config_contents));

    if (!ot_gfile_replace_contents_fsync (new_config_path, new_config_contents_bytes,
                                          cancellable, error))
      return FALSE;
  }

  return TRUE;
}
Esempio n. 15
0
static AesCtrState *
setup_aes_decrypt()
{
/* NIST SP800-38a section F.5.2; CTR-AES128 Decrypt */
  const guint8 Key[]={ 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c };
  const guint8 IV[] = { 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff };
 AesCtrState *state;
 GstBuffer *gkey;
 GBytes *giv;

 gkey = gst_buffer_new_allocate (NULL,sizeof(Key),NULL);
 fail_if(gkey==NULL);
 gst_buffer_fill(gkey,0,Key,sizeof(Key));
 giv = g_bytes_new_static(IV,sizeof(IV));
 fail_if(giv==NULL);
 state = gst_aes_ctr_decrypt_new(gkey, giv);
 fail_if(state==NULL);
 g_bytes_unref(giv);
 gst_buffer_unref(gkey);

 return state;
}
Esempio n. 16
0
/**
 * cockpit_web_response_queue:
 * @self: the response
 * @block: the block of data to queue
 *
 * Queue a single block of data on the response. Will be sent
 * during the main loop.
 *
 * See cockpit_web_response_content() for a simple way to
 * avoid queueing individual blocks.
 *
 * If this function returns %FALSE, then the response has failed
 * or has been completed elsewhere. The block was ignored and
 * queuing more blocks doesn't makes sense.
 *
 * After done queuing all your blocks call
 * cockpit_web_response_complete().
*
 * Returns: Whether queuing more blocks makes sense
 */
gboolean
cockpit_web_response_queue (CockpitWebResponse *self,
                            GBytes *block)
{
  gchar *data;
  GBytes *bytes;

  g_return_val_if_fail (block != NULL, FALSE);
  g_return_val_if_fail (self->complete == FALSE, FALSE);

  if (self->failed)
    {
      g_debug ("%s: ignoring queued block after failure", self->logname);
      return FALSE;
    }

  g_debug ("%s: queued %d bytes", self->logname, (int)g_bytes_get_size (block));

  if (!self->chunked)
    {
      queue_bytes (self, block);
    }
  else
    {
      /* Required for chunked transfer encoding. */
      data = g_strdup_printf ("%x\r\n", (unsigned int)g_bytes_get_size (block));
      bytes = g_bytes_new_take (data, strlen (data));
      queue_bytes (self, bytes);
      g_bytes_unref (bytes);

      queue_bytes (self, block);

      bytes = g_bytes_new_static ("\r\n", 2);
      queue_bytes (self, bytes);
      g_bytes_unref (bytes);
    }

  return TRUE;
}
Esempio n. 17
0
static void
register_lazy_static_resources_unlocked (void)
{
  GStaticResource *list;

  do
    list = lazy_register_resources;
  while (!g_atomic_pointer_compare_and_exchange (&lazy_register_resources, list, NULL));

  while (list != NULL)
    {
      GBytes *bytes = g_bytes_new_static (list->data, list->data_len);
      GResource *resource = g_resource_new_from_data (bytes, NULL);
      if (resource)
        {
          g_resources_register_unlocked (resource);
          g_atomic_pointer_set (&list->resource, resource);
        }
      g_bytes_unref (bytes);

      list = list->next;
    }
}
Esempio n. 18
0
static void
queue_block (CockpitWebResponse *self,
             GBytes *block)
{
  gsize length = g_bytes_get_size (block);
  GBytes *bytes;
  gchar *data;

  /*
   * We cannot queue chunks of length zero. Besides being silly, this
   * messes with chunked encoding. The 0 length block means end of
   * response.
   */
  if (length == 0)
    return;

  g_debug ("%s: queued %d bytes", self->logname, (int)length);

  if (!self->chunked)
    {
      queue_bytes (self, block);
    }
  else
    {
      /* Required for chunked transfer encoding. */
      data = g_strdup_printf ("%x\r\n", (unsigned int)length);
      bytes = g_bytes_new_take (data, strlen (data));
      queue_bytes (self, bytes);
      g_bytes_unref (bytes);

      queue_bytes (self, block);

      bytes = g_bytes_new_static ("\r\n", 2);
      queue_bytes (self, bytes);
      g_bytes_unref (bytes);
    }
}
Esempio n. 19
0
static void
add_dynamic_args_to_array (gchar ***key,
                           gchar **config_args,
                           JsonObject *options)
{
  GPtrArray *arr = NULL;
  gint length;
  gint i;

  g_assert (config_args != NULL);
  g_assert (key != NULL);

  arr = g_ptr_array_new ();
  length = g_strv_length (config_args);
  for (i = 0; i < length; i++)
    {
      GString *s = g_string_new ("");
      GBytes *input = g_bytes_new_static (config_args[i], strlen(config_args[i]) + 1);
      GList *output = cockpit_template_expand (input, substitute_json_string,
                                               "${", "}", options);
      GList *l;
      for (l = output; l != NULL; l = g_list_next (l))
        {
          gsize size;
          gconstpointer data = g_bytes_get_data (l->data, &size);
          g_string_append_len (s, data, size);
        }

      g_ptr_array_add (arr, g_string_free (s, FALSE));
      g_bytes_unref (input);
      g_list_free_full (output, (GDestroyNotify) g_bytes_unref);
    }

  g_ptr_array_add (arr, NULL);
  *key = (gchar **)g_ptr_array_free (arr, FALSE);
}
Esempio n. 20
0
static gboolean
redirect_to_checksum_path (CockpitWebService *service,
                           CockpitWebResponse *response,
                           const gchar *checksum,
                           const gchar *path)
{
  CockpitCreds *creds;
  gchar *location;
  const gchar *body;
  GBytes *bytes;
  gboolean ret;
  gsize length;

  creds = cockpit_web_service_get_creds (service);
  location = g_strdup_printf ("/%s/$%s%s",
                              cockpit_creds_get_application (creds),
                              checksum, path);

  body = "<html><head><title>Temporary redirect</title></head>"
         "<body>Access via checksum</body></html>";

  length = strlen (body);
  cockpit_web_response_headers (response, 307, "Temporary Redirect", length,
                                "Content-Type", "text/html",
                                "Location", location,
                                NULL);
  g_free (location);

  bytes = g_bytes_new_static (body, length);
  ret = cockpit_web_response_queue (response, bytes);
  if (ret)
    cockpit_web_response_complete (response);
  g_bytes_unref (bytes);

  return ret;
}
static gboolean
_ostree_bootloader_syslinux_write_config (OstreeBootloader          *bootloader,
                                     int                    bootversion,
                                     GCancellable          *cancellable,
                                     GError               **error)
{
  gboolean ret = FALSE;
  OstreeBootloaderSyslinux *self = OSTREE_BOOTLOADER_SYSLINUX (bootloader);
  gs_unref_object GFile *new_config_path = NULL;
  gs_free char *config_contents = NULL;
  gs_free char *new_config_contents = NULL;
  gs_unref_ptrarray GPtrArray *new_lines = NULL;
  gs_unref_ptrarray GPtrArray *tmp_lines = NULL;
  gs_free char *kernel_arg = NULL;
  gboolean saw_default = FALSE;
  gboolean regenerate_default = FALSE;
  gboolean parsing_label = FALSE;
  char **lines = NULL;
  char **iter;
  guint i;

  new_config_path = ot_gfile_resolve_path_printf (self->sysroot->path, "boot/loader.%d/syslinux.cfg",
                                                  bootversion);

  /* This should follow the symbolic link to the current bootversion. */
  config_contents = gs_file_load_contents_utf8 (self->config_path, cancellable, error);
  if (!config_contents)
    goto out;

  lines = g_strsplit (config_contents, "\n", -1);
  new_lines = g_ptr_array_new_with_free_func (g_free);
  tmp_lines = g_ptr_array_new_with_free_func (g_free);
  
  /* Note special iteration condition here; we want to also loop one
   * more time at the end where line = NULL to ensure we finish off
   * processing the last LABEL.
   */
  iter = lines;
  while (TRUE)
    {
      char *line = *iter;
      gboolean skip = FALSE;

      if (parsing_label && 
          (line == NULL || !g_str_has_prefix (line, "\t")))
        {
          parsing_label = FALSE;
          if (kernel_arg == NULL)
            {
              g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                                   "No KERNEL argument found after LABEL");
              goto out;
            }

          /* If this is a non-ostree kernel, just emit the lines
           * we saw.
           */
          if (!g_str_has_prefix (kernel_arg, "/ostree/"))
            {
              for (i = 0; i < tmp_lines->len; i++)
                {
                  g_ptr_array_add (new_lines, tmp_lines->pdata[i]);
                  tmp_lines->pdata[i] = NULL; /* Transfer ownership */
                }
            }
          else
            {
              /* Otherwise, we drop the config on the floor - it
               * will be regenerated.
               */
              g_ptr_array_set_size (tmp_lines, 0);
            }
        }

      if (line == NULL)
        break;

      if (!parsing_label &&
          (g_str_has_prefix (line, "LABEL ")))
        {
          parsing_label = TRUE;
          g_ptr_array_set_size (tmp_lines, 0);
        }
      else if (parsing_label && g_str_has_prefix (line, "\tKERNEL "))
        {
          g_free (kernel_arg);
          kernel_arg = g_strdup (line + strlen ("\tKERNEL "));
        }
      else if (!parsing_label &&
               (g_str_has_prefix (line, "DEFAULT ")))
        {
          saw_default = TRUE;
          /* XXX Searching for patterns in the title is rather brittle,
           *     but this hack is at least noted in the code that builds
           *     the title to hopefully avoid regressions. */
          if (g_str_has_prefix (line, "DEFAULT ostree:") ||  /* old format */
              strstr (line, "(ostree") != NULL)              /* new format */
            {
              regenerate_default = TRUE;
            }
          skip = TRUE;
        }
      
      if (skip)
        {
          g_free (line);
        }
      else
        {
          if (parsing_label)
            {
              g_ptr_array_add (tmp_lines, line);
            }
          else
            {
              g_ptr_array_add (new_lines, line);
            }
        }
      /* Transfer ownership */
      *iter = NULL;
      iter++;
    }

  if (!saw_default)
    regenerate_default = TRUE;

  if (!append_config_from_boostree_loader_entries (self, regenerate_default,
                                               bootversion, new_lines,
                                               cancellable, error))
    goto out;

  new_config_contents = _ostree_sysroot_join_lines (new_lines);
  {
    gs_unref_bytes GBytes *new_config_contents_bytes =
      g_bytes_new_static (new_config_contents,
                          strlen (new_config_contents));

    if (!ot_gfile_replace_contents_fsync (new_config_path, new_config_contents_bytes,
                                          cancellable, error))
      goto out;
  }
  
  ret = TRUE;
 out:
  g_free (lines); /* Note we freed elements individually */
  return ret;
}
Esempio n. 22
0
static void
cockpit_auth_remote_login_async (CockpitAuth *self,
                                 const gchar *application,
                                 const gchar *type,
                                 GHashTable *headers,
                                 const gchar *remote_peer,
                                 GAsyncReadyCallback callback,
                                 gpointer user_data)
{
  GSimpleAsyncResult *task;
  AuthData *ad = NULL;
  GBytes *input = NULL;
  GBytes *auth_bytes = NULL;
  gchar *user = NULL;
  gchar *password = NULL; /* owned by input */

  const gchar *data = NULL;
  const gchar *command;
  const gchar *host;
  const gchar *host_arg;
  gint next_arg = 1;

  const gchar *argv[] = {
      cockpit_ws_ssh_program,
      NULL,
      NULL,
      NULL,
      NULL,
      NULL,
      NULL,
  };

  task = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
                                    cockpit_auth_remote_login_async);
  if (g_strcmp0 (type, "basic") == 0)
    {
      input = cockpit_auth_parse_authorization (headers, TRUE);
      data = g_bytes_get_data (input, NULL);

      password = strchr (data, ':');
      if (password != NULL)
        {
          user = g_strndup (data, password - data);
          password++;
          auth_bytes = g_bytes_new_static (password, strlen(password));
        }
    }
  else
    {
      input = cockpit_auth_parse_authorization (headers, FALSE);
      if (input)
        auth_bytes = g_bytes_ref (input);
    }

  if (application && auth_bytes && input)
    {
      command = type_option (SSH_SECTION, "command", cockpit_ws_ssh_program);
      argv[0] = command;

      host = application_parse_host (application);
      if (host)
        {
          host_arg = host;
          if (g_strcmp0 (remote_peer, "127.0.0.1") == 0 ||
              g_strcmp0 (remote_peer, "::1") == 0 ||
              cockpit_conf_bool (SSH_SECTION, "allowUnknown", FALSE))
            {
              argv[next_arg++] = "--prompt-unknown-hostkey";
            }
        }
      else
        {
          argv[next_arg++] = "--ignore-hostkey";
          if (cockpit_conf_string (SSH_SECTION, "host"))
            host_arg = cockpit_conf_string (SSH_SECTION, "host");
          else
            host_arg = "localhost";
        }

      argv[next_arg++] = host_arg;
      argv[next_arg++] = user;
      ad = create_auth_data (self, host_arg, application,
                             SSH_SECTION, remote_peer, command, input);
      start_auth_process (self, ad, auth_bytes, task,
                          cockpit_auth_remote_login_async, argv);
    }
  else
    {
      g_simple_async_result_set_error (task, COCKPIT_ERROR, COCKPIT_ERROR_AUTHENTICATION_FAILED,
                                       "Basic authentication required");
      g_simple_async_result_complete_in_idle (task);
    }

  if (auth_bytes)
    g_bytes_unref (auth_bytes);

  if (input)
    g_bytes_unref (input);

  if (ad)
    auth_data_unref (ad);

  if (user)
    g_free (user);

  g_object_unref (task);
}
Esempio n. 23
0
static void
my_dialog_init (MyDialog *dialog)
{
  gtk_widget_init_template (GTK_WIDGET (dialog));
}

static void
my_dialog_class_init (MyDialogClass *class)
{
  gchar *buffer;
  gsize size;
  GBytes *bytes;

  g_file_get_contents ("mydialog.ui", &buffer, &size, NULL);
  bytes = g_bytes_new_static (buffer, size);
  gtk_widget_class_set_template (GTK_WIDGET_CLASS (class), bytes);
  g_bytes_unref (bytes);
}

static void
show_dialog_from_template (GtkWindow *parent)
{
  GtkWidget *dialog;

  dialog = g_object_new (my_dialog_get_type (),
                         "title", "Template",
                         "transient-for", parent,
                         NULL);

  add_buttons (dialog);
Esempio n. 24
0
/**
 * cockpit_web_response_error:
 * @self: the response
 * @status: the HTTP status code
 * @headers: headers to include or NULL
 * @format: printf format of error message
 *
 * Send an error message with a basic HTML page containing
 * the error.
 */
void
cockpit_web_response_error (CockpitWebResponse *self,
                            guint code,
                            GHashTable *headers,
                            const gchar *format,
                            ...)
{
  va_list var_args;
  gchar *reason = NULL;
  const gchar *message;
  GBytes *input = NULL;
  GList *output, *l;
  GError *error = NULL;

  g_return_if_fail (COCKPIT_IS_WEB_RESPONSE (self));

  if (format)
    {
      va_start (var_args, format);
      reason = g_strdup_vprintf (format, var_args);
      va_end (var_args);
      message = reason;
    }
  else
    {
      switch (code)
        {
        case 400:
          message = "Bad request";
          break;
        case 401:
          message = "Not Authorized";
          break;
        case 403:
          message = "Forbidden";
          break;
        case 404:
          message = "Not Found";
          break;
        case 405:
          message = "Method Not Allowed";
          break;
        case 413:
          message = "Request Entity Too Large";
          break;
        case 502:
          message = "Remote Page is Unavailable";
          break;
        case 500:
          message = "Internal Server Error";
          break;
        default:
          if (code < 100)
            reason = g_strdup_printf ("%u Continue", code);
          else if (code < 200)
            reason = g_strdup_printf ("%u OK", code);
          else if (code < 300)
            reason = g_strdup_printf ("%u Moved", code);
          else
            reason = g_strdup_printf ("%u Failed", code);
          message = reason;
          break;
        }
    }

  g_debug ("%s: returning error: %u %s", self->logname, code, message);

  if (cockpit_web_failure_resource)
    {
      input = g_resources_lookup_data (cockpit_web_failure_resource, G_RESOURCE_LOOKUP_FLAGS_NONE, &error);
      if (input == NULL)
        {
          g_critical ("couldn't load: %s: %s", cockpit_web_failure_resource, error->message);
          g_error_free (error);
        }
    }

  if (!input)
    input = g_bytes_new_static (default_failure_template, strlen (default_failure_template));

  if (headers)
    {
      if (!g_hash_table_lookup (headers, "Content-Type"))
        g_hash_table_replace (headers, g_strdup ("Content-Type"), g_strdup ("text/html; charset=utf8"));
      cockpit_web_response_headers_full (self, code, message, -1, headers);
    }
  else
    {
      cockpit_web_response_headers (self, code, message, -1, "Content-Type", "text/html; charset=utf8", NULL);
    }

  output = cockpit_template_expand (input, substitute_message, (gpointer)message);
  g_bytes_unref (input);

  for (l = output; l != NULL; l = g_list_next (l))
    {
      if (!cockpit_web_response_queue (self, l->data))
        break;
    }
  if (l == NULL)
    cockpit_web_response_complete (self);
  g_list_free_full (output, (GDestroyNotify)g_bytes_unref);

  g_free (reason);
}