예제 #1
0
static gboolean
dsa_subject_public_key_from_attributes (GckAttributes *attrs,
                                        gulong klass,
                                        GNode *info_asn)
{
	const GckAttribute *value, *g, *q, *p;
	GNode *key_asn, *params_asn;
	GBytes *key;

	p = gck_attributes_find (attrs, CKA_PRIME);
	q = gck_attributes_find (attrs, CKA_SUBPRIME);
	g = gck_attributes_find (attrs, CKA_BASE);
	value = gck_attributes_find (attrs, CKA_VALUE);

	if (p == NULL || gck_attribute_is_invalid (p) ||
	    q == NULL || gck_attribute_is_invalid (q) ||
	    g == NULL || gck_attribute_is_invalid (g) ||
	    value == NULL || gck_attribute_is_invalid (value))
		return FALSE;

	key_asn = egg_asn1x_create (pk_asn1_tab, "DSAPublicPart");
	g_return_val_if_fail (key_asn, FALSE);

	params_asn = egg_asn1x_create (pk_asn1_tab, "DSAParameters");
	g_return_val_if_fail (params_asn, FALSE);

	egg_asn1x_take_integer_as_usg (egg_asn1x_node (params_asn, "p", NULL),
	                               g_bytes_new_with_free_func (p->value, p->length,
	                                                             gck_attributes_unref,
	                                                             gck_attributes_ref (attrs)));
	egg_asn1x_take_integer_as_usg (egg_asn1x_node (params_asn, "q", NULL),
	                               g_bytes_new_with_free_func (q->value, q->length,
	                                                             gck_attributes_unref,
	                                                             gck_attributes_ref (attrs)));
	egg_asn1x_take_integer_as_usg (egg_asn1x_node (params_asn, "g", NULL),
	                               g_bytes_new_with_free_func (g->value, g->length,
	                                                             gck_attributes_unref,
	                                                             gck_attributes_ref (attrs)));

	/* Are these attributes for a public or private key? */
	if (klass == CKO_PRIVATE_KEY) {

		/* We need to calculate the public from the private key */
		if (!dsa_subject_public_key_from_private (key_asn, p, q, g, value))
			g_return_val_if_reached (FALSE);

	} else if (klass == CKO_PUBLIC_KEY) {
		egg_asn1x_take_integer_as_usg (key_asn,
		                               g_bytes_new_with_free_func (value->value, value->length,
		                                                             gck_attributes_unref,
		                                                             gck_attributes_ref (attrs)));
	} else {
		g_assert_not_reached ();
	}

	key = egg_asn1x_encode (key_asn, NULL);
	egg_asn1x_destroy (key_asn);

	egg_asn1x_set_bits_as_raw (egg_asn1x_node (info_asn, "subjectPublicKey", NULL),
	                           key, g_bytes_get_size (key) * 8);
	egg_asn1x_set_any_from (egg_asn1x_node (info_asn, "algorithm", "parameters", NULL), params_asn);

	egg_asn1x_set_oid_as_quark (egg_asn1x_node (info_asn, "algorithm", "algorithm", NULL), GCR_OID_PKIX1_DSA);

	g_bytes_unref (key);
	egg_asn1x_destroy (params_asn);
	return TRUE;
}
예제 #2
0
/**
 * gcr_certificate_request_complete:
 * @self: a certificate request
 * @cancellable: a cancellation object
 * @error: location to place an error on failure
 *
 * Complete and sign a certificate request, so that it can be encoded
 * and sent to a certificate authority.
 *
 * This call may block as it signs the request using the private key.
 *
 * Returns: whether certificate request was successfully completed or not
 */
gboolean
gcr_certificate_request_complete (GcrCertificateRequest *self,
                                  GCancellable *cancellable,
                                  GError **error)
{
	GNode *subject_public_key;
	const gulong *mechanisms;
	gsize n_mechanisms;
	GckMechanism mechanism = { 0, };
	GQuark algorithm = 0;
	GBytes *tbs;
	GckSession *session;
	guchar *signature;
	gsize n_signature;
	gboolean ret;

	g_return_val_if_fail (GCR_IS_CERTIFICATE_REQUEST (self), FALSE);
	g_return_val_if_fail (cancellable == NULL || G_CANCELLABLE (cancellable), FALSE);
	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

	subject_public_key = _gcr_subject_public_key_load (self->private_key,
	                                                   cancellable, error);
	if (subject_public_key == NULL)
		return FALSE;

	ret = prepare_subject_public_key_and_mechanisms (self, subject_public_key,
	                                                 &algorithm, &mechanisms,
	                                                 &n_mechanisms, error);

	if (!ret) {
		egg_asn1x_destroy (subject_public_key);
		return FALSE;
	}

	/* Figure out which mechanism to use */
	mechanism.type = _gcr_key_mechanisms_check (self->private_key, mechanisms,
	                                            n_mechanisms, CKA_SIGN,
	                                            cancellable, NULL);
	if (mechanism.type == GCK_INVALID) {
		egg_asn1x_destroy (subject_public_key);
		g_set_error (error, GCK_ERROR, CKR_KEY_TYPE_INCONSISTENT,
		             _("The key cannot be used to sign the request"));
		return FALSE;
	}

	tbs = prepare_to_be_signed (self, &mechanism);
	session = gck_object_get_session (self->private_key);
	signature = gck_session_sign_full (session, self->private_key, &mechanism,
	                                   g_bytes_get_data (tbs, NULL),
	                                   g_bytes_get_size (tbs),
	                                   &n_signature, cancellable, error);
	g_object_unref (session);
	g_bytes_unref (tbs);

	if (!signature) {
		egg_asn1x_destroy (subject_public_key);
		return FALSE;
	}

	encode_take_signature_into_request (self, algorithm, subject_public_key,
	                                    signature, n_signature);
	egg_asn1x_destroy (subject_public_key);
	return TRUE;
}
예제 #3
0
파일: dfu-patch.c 프로젝트: vathpela/fwupd
/**
 * dfu_patch_apply:
 * @self: a #DfuPatch
 * @blob: a #GBytes, typically the old firmware image
 * @flags: a #DfuPatchApplyFlags, e.g. %DFU_PATCH_APPLY_FLAG_IGNORE_CHECKSUM
 * @error: a #GError, or %NULL
 *
 * Apply the currently loaded patch to a new firmware image.
 *
 * Return value: A #GBytes, typically saved as the new firmware file
 **/
GBytes *
dfu_patch_apply (DfuPatch *self, GBytes *blob, DfuPatchApplyFlags flags, GError **error)
{
	DfuPatchPrivate *priv = GET_PRIVATE (self);
	const guint8 *data_old;
	gsize sz;
	gsize sz_max = 0;
	g_autofree guint8 *data_new = NULL;
	g_autoptr(GBytes) blob_checksum_new = NULL;
	g_autoptr(GBytes) blob_checksum = NULL;
	g_autoptr(GBytes) blob_new = NULL;

	/* not loaded yet */
	if (priv->chunks->len == 0) {
		g_set_error_literal (error,
				     FWUPD_ERROR,
				     FWUPD_ERROR_INVALID_FILE,
				     "no patches loaded");
		return NULL;
	}

	/* get the hash of the old firmware file */
	blob_checksum = dfu_patch_calculate_checksum (blob);
	if ((flags & DFU_PATCH_APPLY_FLAG_IGNORE_CHECKSUM) == 0 &&
	    !g_bytes_equal (blob_checksum, priv->checksum_old)) {
		g_autofree gchar *actual = _g_bytes_to_string (blob_checksum);
		g_autofree gchar *expect = _g_bytes_to_string (priv->checksum_old);
		g_set_error (error,
			     FWUPD_ERROR,
			     FWUPD_ERROR_INVALID_FILE,
			     "checksum for source did not match, expected %s, got %s",
			     expect, actual);
		return NULL;
	}

	/* get the size of the new image size */
	for (guint i = 0; i < priv->chunks->len; i++) {
		DfuPatchChunk *chunk = g_ptr_array_index (priv->chunks, i);
		gsize chunk_sz = g_bytes_get_size (chunk->blob);
		if (chunk->off + chunk_sz > sz_max)
			sz_max = chunk->off + chunk_sz;
	}

	/* first, copy the data buffer */
	data_old = g_bytes_get_data (blob, &sz);
	if (sz_max < sz) {
		g_set_error_literal (error,
				     FWUPD_ERROR,
				     FWUPD_ERROR_INVALID_FILE,
				     "binary patch cannot truncate binary");
		return NULL;
	}
	if (sz == sz_max) {
		g_debug ("binary staying same size: %" G_GSIZE_FORMAT, sz);
	} else {
		g_debug ("binary growing from: %" G_GSIZE_FORMAT
			 " to %" G_GSIZE_FORMAT, sz, sz_max);
	}

	data_new = g_malloc0 (sz_max);
	memcpy (data_new, data_old, MIN (sz, sz_max));
	for (guint i = 0; i < priv->chunks->len; i++) {
		DfuPatchChunk *chunk = g_ptr_array_index (priv->chunks, i);
		const guint8 *chunk_data;
		gsize chunk_sz;

		/* bigger than the total size */
		chunk_data = g_bytes_get_data (chunk->blob, &chunk_sz);
		if (chunk->off + chunk_sz > sz_max) {
			g_set_error (error,
				     FWUPD_ERROR,
				     FWUPD_ERROR_INVALID_FILE,
				     "cannot apply chunk as larger than max size");
			return NULL;
		}

		/* apply one chunk */
		g_debug ("applying chunk %u/%u @0x%04x (length %" G_GSIZE_FORMAT ")",
			 i + 1, priv->chunks->len, chunk->off, chunk_sz);
		memcpy (data_new + chunk->off, chunk_data, chunk_sz);
	}

	/* check we got the desired hash */
	blob_new = g_bytes_new (data_new, sz_max);
	blob_checksum_new = dfu_patch_calculate_checksum (blob_new);
	if ((flags & DFU_PATCH_APPLY_FLAG_IGNORE_CHECKSUM) == 0 &&
	    !g_bytes_equal (blob_checksum_new, priv->checksum_new)) {
		g_autofree gchar *actual = _g_bytes_to_string (blob_checksum_new);
		g_autofree gchar *expect = _g_bytes_to_string (priv->checksum_new);
		g_set_error (error,
			     FWUPD_ERROR,
			     FWUPD_ERROR_INVALID_FILE,
			     "checksum for result did not match, expected %s, got %s",
			     expect, actual);
		return NULL;
	}

	/* success */
	return g_steal_pointer (&blob_new);
}
예제 #4
0
static gboolean
builder_source_file_download (BuilderSource *source,
                              gboolean update_vcs,
                              BuilderContext *context,
                              GError **error)
{
  BuilderSourceFile *self = BUILDER_SOURCE_FILE (source);
  g_autoptr(GFile) file = NULL;
  gboolean is_local, is_inline;
  g_autoptr (GFile) dir = NULL;
  g_autofree char *dir_path = NULL;
  g_autofree char *sha256 = NULL;
  g_autofree char *base_name = NULL;
  g_autoptr(GBytes) content = NULL;

  file = get_source_file (self, context, &is_local, &is_inline, error);
  if (file == NULL)
    return FALSE;

  base_name = g_file_get_basename (file);

  if (g_file_query_exists (file, NULL))
    {
      if (is_local && self->sha256 != NULL && *self->sha256 != 0)
        {
          g_autofree char *data = NULL;
          gsize len;

          if (!g_file_load_contents (file, NULL, &data, &len, NULL, error))
            return FALSE;

          sha256 = g_compute_checksum_for_string (G_CHECKSUM_SHA256, data, len);
          if (strcmp (sha256, self->sha256) != 0)
            {
              g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                           "Wrong sha256 for %s, expected %s, was %s", base_name, self->sha256, sha256);
              return FALSE;
            }
        }
      return TRUE;
    }

  if (is_local)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Can't find file at %s", self->path);
      return FALSE;
    }

  content = download_uri (self->url,
                          context,
                          error);
  if (content == NULL)
    return FALSE;

  sha256 = g_compute_checksum_for_string (G_CHECKSUM_SHA256,
                                          g_bytes_get_data (content, NULL),
                                          g_bytes_get_size (content));

  /* sha256 is optional for inline data */
  if (((self->sha256 != NULL && *self->sha256 != 0) || !is_inline) &&
      strcmp (sha256, self->sha256) != 0)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                   "Wrong sha256 for %s, expected %s, was %s", base_name, self->sha256, sha256);
      return FALSE;
    }

  dir = g_file_get_parent (file);
  dir_path = g_file_get_path (dir);
  g_mkdir_with_parents (dir_path, 0755);

  if (!g_file_replace_contents (file,
                                g_bytes_get_data (content, NULL),
                                g_bytes_get_size (content),
                                NULL, FALSE, G_FILE_CREATE_NONE, NULL,
                                NULL, error))
    return FALSE;

  return TRUE;
}
gboolean
_ostree_static_delta_part_open (GInputStream   *part_in,
                                GBytes         *inline_part_bytes,
                                OstreeStaticDeltaOpenFlags flags,
                                const char     *expected_checksum,
                                GVariant    **out_part,
                                GCancellable *cancellable,
                                GError      **error)
{
  gboolean ret = FALSE;
  const gboolean trusted = (flags & OSTREE_STATIC_DELTA_OPEN_FLAGS_VARIANT_TRUSTED) > 0;
  const gboolean skip_checksum = (flags & OSTREE_STATIC_DELTA_OPEN_FLAGS_SKIP_CHECKSUM) > 0;
  gsize bytes_read;
  guint8 comptype;
  g_autoptr(GChecksum) checksum = NULL;
  g_autoptr(GInputStream) checksum_in = NULL;
  g_autoptr(GVariant) ret_part = NULL;
  GInputStream *source_in;

  /* We either take a fd or a GBytes reference */
  g_return_val_if_fail (G_IS_FILE_DESCRIPTOR_BASED (part_in) || inline_part_bytes != NULL, FALSE);
  g_return_val_if_fail (skip_checksum || expected_checksum != NULL, FALSE);

  if (!skip_checksum)
    {
      checksum = g_checksum_new (G_CHECKSUM_SHA256);
      checksum_in = (GInputStream*)ostree_checksum_input_stream_new (part_in, checksum);
      source_in = checksum_in;
    }
  else
    {
      source_in = part_in;
    }

  { guint8 buf[1];
    /* First byte is compression type */
    if (!g_input_stream_read_all (source_in, buf, sizeof(buf), &bytes_read,
                                  cancellable, error))
      {
        g_prefix_error (error, "Reading initial compression flag byte: ");
      goto out;
      }
    comptype = buf[0];
  }

  switch (comptype)
    {
    case 0:
      if (!inline_part_bytes)
        {
          int part_fd = g_file_descriptor_based_get_fd ((GFileDescriptorBased*)part_in);

          /* No compression, no checksums - a fast path */
          if (!ot_util_variant_map_fd (part_fd, 1, G_VARIANT_TYPE (OSTREE_STATIC_DELTA_PART_PAYLOAD_FORMAT_V0),
                                       trusted, &ret_part, error))
            goto out;
        }
      else
        {
          g_autoptr(GBytes) content_bytes = g_bytes_new_from_bytes (inline_part_bytes, 1,
                                                                    g_bytes_get_size (inline_part_bytes) - 1);
          ret_part = g_variant_new_from_bytes (G_VARIANT_TYPE (OSTREE_STATIC_DELTA_PART_PAYLOAD_FORMAT_V0),
                                               content_bytes, trusted);
          g_variant_ref_sink (ret_part);
        }

      if (!skip_checksum)
        g_checksum_update (checksum, g_variant_get_data (ret_part),
                           g_variant_get_size (ret_part));
      
      break;
    case 'x':
      {
        g_autofree char *tmppath = g_strdup ("/var/tmp/ostree-delta-XXXXXX");
        g_autoptr(GConverter) decomp = (GConverter*) _ostree_lzma_decompressor_new ();
        g_autoptr(GInputStream) convin = g_converter_input_stream_new (source_in, decomp);
        g_autoptr(GOutputStream) unpacked_out = NULL;
        glnx_fd_close int unpacked_fd = -1;
        gssize n_bytes_written;

        unpacked_fd = g_mkstemp_full (tmppath, O_RDWR | O_CLOEXEC, 0640);
        if (unpacked_fd < 0)
          {
            glnx_set_error_from_errno (error);
            goto out;
          }
        
        /* Now make it autocleanup on process exit - in the future, we
         * should consider caching unpacked deltas as well.
         */
        if (unlink (tmppath) < 0)
          {
            glnx_set_error_from_errno (error);
            goto out;
          }
        
        unpacked_out = g_unix_output_stream_new (unpacked_fd, FALSE);

        n_bytes_written = g_output_stream_splice (unpacked_out, convin,
                                                  G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE |
                                                  G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
                                                  cancellable, error);
        if (n_bytes_written < 0)
          goto out;

        if (!ot_util_variant_map_fd (unpacked_fd, 0, G_VARIANT_TYPE (OSTREE_STATIC_DELTA_PART_PAYLOAD_FORMAT_V0),
                                     trusted, &ret_part, error))
          goto out;
      }
      break;
    default:
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                   "Invalid compression type '%u'", comptype);
      goto out;
    }

  if (checksum)
    {
      const char *actual_checksum = g_checksum_get_string (checksum);
      g_assert (expected_checksum != NULL);
      if (strcmp (actual_checksum, expected_checksum) != 0)
        {
          g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                       "Checksum mismatch in static delta part; expected=%s actual=%s",
                       expected_checksum, actual_checksum);
          goto out;
        }
    }
        
  ret = TRUE;
  *out_part = g_steal_pointer (&ret_part);
 out:
  return ret;
}
예제 #6
0
파일: fu-provider.c 프로젝트: goliate/fwupd
/**
 * fu_provider_schedule_update:
 **/
static gboolean
fu_provider_schedule_update (FuProvider *provider,
			     FuDevice *device,
			     GInputStream *stream,
			     GError **error)
{
	gchar tmpname[] = {"XXXXXX.cap"};
	guint i;
	_cleanup_bytes_unref_ GBytes *fwbin = NULL;
	_cleanup_free_ gchar *dirname = NULL;
	_cleanup_free_ gchar *filename = NULL;
	_cleanup_object_unref_ FuDevice *device_tmp = NULL;
	_cleanup_object_unref_ FuPending *pending = NULL;
	_cleanup_object_unref_ GFile *file = NULL;

	/* id already exists */
	pending = fu_pending_new ();
	device_tmp = fu_pending_get_device (pending, fu_device_get_id (device), NULL);
	if (device_tmp != NULL) {
		g_set_error (error,
			     FWUPD_ERROR,
			     FWUPD_ERROR_ALREADY_PENDING,
			     "%s is already scheduled to be updated",
			     fu_device_get_id (device));
		return FALSE;
	}

	/* create directory */
	dirname = g_build_filename (LOCALSTATEDIR, "lib", "fwupd", NULL);
	file = g_file_new_for_path (dirname);
	if (!g_file_query_exists (file, NULL)) {
		if (!g_file_make_directory_with_parents (file, NULL, error))
			return FALSE;
	}

	/* get a random filename */
	for (i = 0; i < 6; i++)
		tmpname[i] = g_random_int_range ('A', 'Z');
	filename = g_build_filename (dirname, tmpname, NULL);

	/* just copy to the temp file */
	fu_provider_set_status (provider, FWUPD_STATUS_SCHEDULING);
	if (!g_seekable_seek (G_SEEKABLE (stream), 0, G_SEEK_SET, NULL, error))
		return FALSE;
	fwbin = g_input_stream_read_bytes (stream,
					   FU_PROVIDER_FIRMWARE_MAX,
					   NULL, error);
	if (fwbin == NULL)
		return FALSE;
	if (!g_file_set_contents (filename,
				  g_bytes_get_data (fwbin, NULL),
				  g_bytes_get_size (fwbin),
				  error))
		return FALSE;

	/* schedule for next boot */
	g_debug ("schedule %s to be installed to %s on next boot",
		 filename, fu_device_get_id (device));
	fu_device_set_metadata (device, FU_DEVICE_KEY_FILENAME_CAB, filename);

	/* add to database */
	if (!fu_pending_add_device (pending, device, error))
		return FALSE;

	/* next boot we run offline */
	return fu_provider_offline_setup (error);
}
예제 #7
0
gboolean
nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self,
                                                    NMSettingWirelessSecurity *setting,
                                                    NMSetting8021x *setting_8021x,
                                                    const char *con_uuid,
                                                    guint32 mtu,
                                                    GError **error)
{
	const char *key_mgmt, *auth_alg;
	const char *psk;

	g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), FALSE);
	g_return_val_if_fail (setting != NULL, FALSE);
	g_return_val_if_fail (con_uuid != NULL, FALSE);
	g_return_val_if_fail (!error || !*error, FALSE);

	key_mgmt = nm_setting_wireless_security_get_key_mgmt (setting);
	if (!add_string_val (self, key_mgmt, "key_mgmt", TRUE, FALSE, error))
		return FALSE;

	auth_alg = nm_setting_wireless_security_get_auth_alg (setting);
	if (!add_string_val (self, auth_alg, "auth_alg", TRUE, FALSE, error))
		return FALSE;

	psk = nm_setting_wireless_security_get_psk (setting);
	if (psk) {
		size_t psk_len = strlen (psk);

		if (psk_len == 64) {
			gs_unref_bytes GBytes *bytes = NULL;

			/* Hex PSK */
			bytes = nm_utils_hexstr2bin (psk);
			if (!bytes) {
				g_set_error (error, NM_SUPPLICANT_ERROR, NM_SUPPLICANT_ERROR_CONFIG,
				             "Cannot add psk to supplicant config due to invalid hex");
				return FALSE;
			}

			if (!nm_supplicant_config_add_option (self,
			                                      "psk",
			                                      g_bytes_get_data (bytes, NULL),
			                                      g_bytes_get_size (bytes),
			                                      TRUE,
			                                      error))
				return FALSE;
		} else if (psk_len >= 8 && psk_len <= 63) {
			/* Use TYPE_STRING here so that it gets pushed to the
			 * supplicant as a string, and therefore gets quoted,
			 * and therefore the supplicant will interpret it as a
			 * passphrase and not a hex key.
			 */
			if (!nm_supplicant_config_add_option_with_type (self, "psk", psk, -1, TYPE_STRING, TRUE, error))
				return FALSE;
		} else {
			g_set_error (error, NM_SUPPLICANT_ERROR, NM_SUPPLICANT_ERROR_CONFIG,
			             "Cannot add psk to supplicant config due to invalid PSK length %u (not between 8 and 63 characters)",
			             (guint) psk_len);
			return FALSE;
		}
	}

	/* Only WPA-specific things when using WPA */
	if (   !strcmp (key_mgmt, "wpa-none")
	    || !strcmp (key_mgmt, "wpa-psk")
	    || !strcmp (key_mgmt, "wpa-eap")) {
		if (!ADD_STRING_LIST_VAL (self, setting, wireless_security, proto, protos, "proto", ' ', TRUE, FALSE, error))
			return FALSE;
		if (!ADD_STRING_LIST_VAL (self, setting, wireless_security, pairwise, pairwise, "pairwise", ' ', TRUE, FALSE, error))
			return FALSE;
		if (!ADD_STRING_LIST_VAL (self, setting, wireless_security, group, groups, "group", ' ', TRUE, FALSE, error))
			return FALSE;
	}

	/* WEP keys if required */
	if (!strcmp (key_mgmt, "none")) {
		NMWepKeyType wep_type = nm_setting_wireless_security_get_wep_key_type (setting);
		const char *wep0 = nm_setting_wireless_security_get_wep_key (setting, 0);
		const char *wep1 = nm_setting_wireless_security_get_wep_key (setting, 1);
		const char *wep2 = nm_setting_wireless_security_get_wep_key (setting, 2);
		const char *wep3 = nm_setting_wireless_security_get_wep_key (setting, 3);

		if (!add_wep_key (self, wep0, "wep_key0", wep_type, error))
			return FALSE;
		if (!add_wep_key (self, wep1, "wep_key1", wep_type, error))
			return FALSE;
		if (!add_wep_key (self, wep2, "wep_key2", wep_type, error))
			return FALSE;
		if (!add_wep_key (self, wep3, "wep_key3", wep_type, error))
			return FALSE;

		if (wep0 || wep1 || wep2 || wep3) {
			gs_free char *value = NULL;

			value = g_strdup_printf ("%d", nm_setting_wireless_security_get_wep_tx_keyidx (setting));
			if (!nm_supplicant_config_add_option (self, "wep_tx_keyidx", value, -1, FALSE, error))
				return FALSE;
		}
	}

	if (auth_alg && !strcmp (auth_alg, "leap")) {
		/* LEAP */
		if (!strcmp (key_mgmt, "ieee8021x")) {
			const char *tmp;

			tmp = nm_setting_wireless_security_get_leap_username (setting);
			if (!add_string_val (self, tmp, "identity", FALSE, FALSE, error))
				return FALSE;

			tmp = nm_setting_wireless_security_get_leap_password (setting);
			if (!add_string_val (self, tmp, "password", FALSE, TRUE, error))
				return FALSE;

			if (!add_string_val (self, "leap", "eap", TRUE, FALSE, error))
				return FALSE;
		} else {
			g_set_error (error, NM_SUPPLICANT_ERROR, NM_SUPPLICANT_ERROR_CONFIG,
			             "Invalid key-mgmt \"%s\" for leap", key_mgmt);
			return FALSE;
		}
	} else {
		/* 802.1x for Dynamic WEP and WPA-Enterprise */
		if (!strcmp (key_mgmt, "ieee8021x") || !strcmp (key_mgmt, "wpa-eap")) {
			if (!setting_8021x) {
				g_set_error (error, NM_SUPPLICANT_ERROR, NM_SUPPLICANT_ERROR_CONFIG,
				             "Cannot set key-mgmt %s with missing 8021x setting", key_mgmt);
				return FALSE;
			}
			if (!nm_supplicant_config_add_setting_8021x (self, setting_8021x, con_uuid, mtu, FALSE, error))
				return FALSE;
		}

		if (!strcmp (key_mgmt, "wpa-eap")) {
			/* If using WPA Enterprise, enable optimized background scanning
			 * to ensure roaming within an ESS works well.
			 */
			if (!nm_supplicant_config_add_option (self, "bgscan", "simple:30:-65:300", -1, FALSE, error))
				return FALSE;

			/* When using WPA-Enterprise, we want to use Proactive Key Caching (also
			 * called Opportunistic Key Caching) to avoid full EAP exchanges when
			 * roaming between access points in the same mobility group.
			 */
			if (!nm_supplicant_config_add_option (self, "proactive_key_caching", "1", -1, FALSE, error))
				return FALSE;
		}
	}

	return TRUE;
}
예제 #8
0
GtkWidget *
do_css_multiplebgs (GtkWidget *do_widget)
{
  if (!window)
    {
      GtkWidget *paned, *container, *child;
      GtkStyleProvider *provider;
      GtkTextBuffer *text;
      GBytes *bytes;

      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
      gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (do_widget));
      gtk_window_set_default_size (GTK_WINDOW (window), 400, 300);
      g_signal_connect (window, "destroy",
                        G_CALLBACK (gtk_widget_destroyed), &window);

      container = gtk_overlay_new ();
      gtk_widget_add_events (container,
                             GDK_ENTER_NOTIFY_MASK |
                             GDK_LEAVE_NOTIFY_MASK |
                             GDK_POINTER_MOTION_MASK);
      gtk_container_add (GTK_CONTAINER (window), container);

      child = gtk_drawing_area_new ();
      gtk_widget_set_name (child, "canvas");
      g_signal_connect (child, "draw",
                        G_CALLBACK (drawing_area_draw), NULL);
      gtk_container_add (GTK_CONTAINER (container), child);

      child = gtk_button_new ();
      gtk_widget_add_events (child,
                             GDK_ENTER_NOTIFY_MASK |
                             GDK_LEAVE_NOTIFY_MASK |
                             GDK_POINTER_MOTION_MASK);
      gtk_overlay_add_overlay (GTK_OVERLAY (container), child);
      gtk_widget_set_name (child, "bricks-button");
      gtk_widget_set_halign (child, GTK_ALIGN_CENTER);
      gtk_widget_set_valign (child, GTK_ALIGN_CENTER);
      gtk_widget_set_size_request (child, 200, 80);

      paned = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
      gtk_overlay_add_overlay (GTK_OVERLAY (container), paned);

      /* Need a filler so we get a handle */
      child = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
      gtk_container_add (GTK_CONTAINER (paned), child);

      text = gtk_text_buffer_new (NULL);
      gtk_text_buffer_create_tag (text,
                                  "warning",
                                  "underline", PANGO_UNDERLINE_SINGLE,
                                  NULL);
      gtk_text_buffer_create_tag (text,
                                  "error",
                                  "underline", PANGO_UNDERLINE_ERROR,
                                  NULL);

      provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());

      container = gtk_scrolled_window_new (NULL, NULL);
      gtk_container_add (GTK_CONTAINER (paned), container);
      child = gtk_text_view_new_with_buffer (text);
      gtk_container_add (GTK_CONTAINER (container), child);
      g_signal_connect (text,
                        "changed",
                        G_CALLBACK (css_text_changed),
                        provider);

      bytes = g_resources_lookup_data ("/css_multiplebgs/gtk.css", 0, NULL);
      gtk_text_buffer_set_text (text, g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes));

      g_signal_connect (provider,
                        "parsing-error",
                        G_CALLBACK (show_parsing_error),
                        gtk_text_view_get_buffer (GTK_TEXT_VIEW (child)));

      apply_css (window, provider);
    }

  if (!gtk_widget_get_visible (window))
    gtk_widget_show_all (window);
  else
    {
      gtk_widget_destroy (window);
      window = NULL;
    }

  return window;
}
gboolean
nm_supplicant_config_add_setting_wireless (NMSupplicantConfig * self,
                                           NMSettingWireless * setting,
                                           guint32 fixed_freq)
{
	NMSupplicantConfigPrivate *priv;
	gboolean is_adhoc, is_ap;
	const char *mode, *band;
	GBytes *ssid;
	const char *bssid;

	g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), FALSE);
	g_return_val_if_fail (setting != NULL, FALSE);

	priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self);

	mode = nm_setting_wireless_get_mode (setting);
	is_adhoc = (mode && !strcmp (mode, "adhoc")) ? TRUE : FALSE;
	is_ap = (mode && !strcmp (mode, "ap")) ? TRUE : FALSE;
	if (is_adhoc || is_ap)
		priv->ap_scan = 2;
	else
		priv->ap_scan = 1;

	ssid = nm_setting_wireless_get_ssid (setting);
	if (!nm_supplicant_config_add_option (self, "ssid",
	                                      (char *) g_bytes_get_data (ssid, NULL),
	                                      g_bytes_get_size (ssid),
	                                      FALSE)) {
		nm_log_warn (LOGD_SUPPLICANT, "Error adding SSID to supplicant config.");
		return FALSE;
	}

	if (is_adhoc) {
		if (!nm_supplicant_config_add_option (self, "mode", "1", -1, FALSE)) {
			nm_log_warn (LOGD_SUPPLICANT, "Error adding mode=1 (adhoc) to supplicant config.");
			return FALSE;
		}
	}

	if (is_ap) {
		if (!nm_supplicant_config_add_option (self, "mode", "2", -1, FALSE)) {
			nm_log_warn (LOGD_SUPPLICANT, "Error adding mode=2 (ap) to supplicant config.");
			return FALSE;
		}
	}

	if ((is_adhoc || is_ap) && fixed_freq) {
		char *str_freq;

		str_freq = g_strdup_printf ("%u", fixed_freq);
		if (!nm_supplicant_config_add_option (self, "frequency", str_freq, -1, FALSE)) {
			g_free (str_freq);
			nm_log_warn (LOGD_SUPPLICANT, "Error adding Ad-Hoc/AP frequency to supplicant config.");
			return FALSE;
		}
		g_free (str_freq);
	}

	/* Except for Ad-Hoc and Hotspot, request that the driver probe for the
	 * specific SSID we want to associate with.
	 */
	if (!(is_adhoc || is_ap)) {
		if (!nm_supplicant_config_add_option (self, "scan_ssid", "1", -1, FALSE))
			return FALSE;
	}

	bssid = nm_setting_wireless_get_bssid (setting);
	if (bssid) {
		if (!nm_supplicant_config_add_option (self, "bssid",
		                                      bssid, strlen (bssid),
		                                      FALSE)) {
			nm_log_warn (LOGD_SUPPLICANT, "Error adding BSSID to supplicant config.");
			return FALSE;
		}
	}

	band = nm_setting_wireless_get_band (setting);
	if (band) {
		const char *freqs = NULL;

		if (!strcmp (band, "a"))
			freqs = FIVE_GHZ_FREQS;
		else if (!strcmp (band, "bg"))
			freqs = TWO_GHZ_FREQS;

		if (freqs && !nm_supplicant_config_add_option (self, "freq_list", freqs, strlen (freqs), FALSE)) {
			nm_log_warn (LOGD_SUPPLICANT, "Error adding frequency list/band to supplicant config.");
			return FALSE;
		}
	}

	// FIXME: channel config item
	
	return TRUE;
}
예제 #10
0
static void
populate_ui (CEPageWifi *self)
{
	CEPageWifiPrivate *priv = CE_PAGE_WIFI_GET_PRIVATE (self);
	NMSettingWireless *setting = priv->setting;
	GBytes *ssid;
	const char *mode;
	const char *band;
	int band_idx = 0;
	int rate_def;
	int tx_power_def;
	int mtu_def;
	char *utf8_ssid;
	const char *s_ifname, *s_mac, *s_bssid;
	GPtrArray *bssid_array;
	char **bssid_list;
	guint32 idx;

	rate_def = ce_get_property_default (NM_SETTING (setting), NM_SETTING_WIRELESS_RATE);
	g_signal_connect (priv->rate, "output",
	                  G_CALLBACK (ce_spin_output_with_automatic),
	                  GINT_TO_POINTER (rate_def));
	g_signal_connect_swapped (priv->rate, "value-changed", G_CALLBACK (ce_page_changed), self);

	tx_power_def = ce_get_property_default (NM_SETTING (setting), NM_SETTING_WIRELESS_TX_POWER);
	g_signal_connect (priv->tx_power, "output",
	                  G_CALLBACK (ce_spin_output_with_automatic),
	                  GINT_TO_POINTER (tx_power_def));
	g_signal_connect_swapped (priv->tx_power, "value-changed", G_CALLBACK (ce_page_changed), self);

	mtu_def = ce_get_property_default (NM_SETTING (setting), NM_SETTING_WIRELESS_MTU);
	g_signal_connect (priv->mtu, "output",
	                  G_CALLBACK (ce_spin_output_with_automatic),
	                  GINT_TO_POINTER (mtu_def));
	g_signal_connect_swapped (priv->mtu, "value-changed", G_CALLBACK (ce_page_changed), self);

	ssid = nm_setting_wireless_get_ssid (setting);
	mode = nm_setting_wireless_get_mode (setting);
	band = nm_setting_wireless_get_band (setting);

	if (ssid)
		utf8_ssid = nm_utils_ssid_to_utf8 (g_bytes_get_data (ssid, NULL),
		                                   g_bytes_get_size (ssid));
	else
		utf8_ssid = g_strdup ("");
	gtk_entry_set_text (priv->ssid, utf8_ssid);
	g_signal_connect_swapped (priv->ssid, "changed", G_CALLBACK (ce_page_changed), self);
	g_free (utf8_ssid);

	/* Default to Infrastructure */
	gtk_combo_box_set_active (priv->mode, 0);
	if (!g_strcmp0 (mode, "ap"))
		gtk_combo_box_set_active (priv->mode, 1);
	if (!g_strcmp0 (mode, "adhoc"))
		gtk_combo_box_set_active (priv->mode, 2);
	mode_combo_changed_cb (priv->mode, self);
	g_signal_connect (priv->mode, "changed", G_CALLBACK (mode_combo_changed_cb), self);

	g_signal_connect (priv->channel, "output",
	                  G_CALLBACK (channel_spin_output_cb),
	                  self);
	g_signal_connect (priv->channel, "input",
	                  G_CALLBACK (channel_spin_input_cb),
	                  self);

	gtk_widget_set_sensitive (GTK_WIDGET (priv->channel), FALSE);
	if (band) {
		if (!strcmp (band, "a")) {
			band_idx = 1;
			gtk_widget_set_sensitive (GTK_WIDGET (priv->channel), TRUE);
		} else if (!strcmp (band, "bg")) {
			band_idx = 2;
			gtk_widget_set_sensitive (GTK_WIDGET (priv->channel), TRUE);
		}
	}

	gtk_combo_box_set_active (priv->band, band_idx);
	g_signal_connect (priv->band, "changed",
	                  G_CALLBACK (band_value_changed_cb),
	                  self);

	/* Update the channel _after_ the band has been set so that it gets
	 * the right values */
	priv->last_channel = nm_setting_wireless_get_channel (setting);
	gtk_spin_button_set_value (priv->channel, (gdouble) priv->last_channel);
	g_signal_connect_swapped (priv->channel, "value-changed", G_CALLBACK (ce_page_changed), self);

	/* BSSID */
	bssid_array = g_ptr_array_new ();
	for (idx = 0; idx < nm_setting_wireless_get_num_seen_bssids (setting); idx++)
		g_ptr_array_add (bssid_array, g_strdup (nm_setting_wireless_get_seen_bssid (setting, idx)));
	g_ptr_array_add (bssid_array, NULL);
	bssid_list = (char **) g_ptr_array_free (bssid_array, FALSE);
	s_bssid = nm_setting_wireless_get_bssid (setting);
	ce_page_setup_mac_combo (CE_PAGE (self), GTK_COMBO_BOX (priv->bssid),
	                         s_bssid, bssid_list);
	g_strfreev (bssid_list);
	g_signal_connect_swapped (priv->bssid, "changed", G_CALLBACK (ce_page_changed), self);

	/* Device MAC address */
        s_ifname = nm_connection_get_interface_name (CE_PAGE (self)->connection);
	s_mac = nm_setting_wireless_get_mac_address (setting);
	ce_page_setup_device_combo (CE_PAGE (self), GTK_COMBO_BOX (priv->device_combo),
	                            NM_TYPE_DEVICE_WIFI, s_ifname,
	                            s_mac, NM_DEVICE_WIFI_PERMANENT_HW_ADDRESS, TRUE);
	g_signal_connect_swapped (priv->device_combo, "changed", G_CALLBACK (ce_page_changed), self);

	/* Cloned MAC address */
	s_mac = nm_setting_wireless_get_cloned_mac_address (setting);
	if (s_mac)
		gtk_entry_set_text (priv->cloned_mac, s_mac);
	g_signal_connect_swapped (priv->cloned_mac, "changed", G_CALLBACK (ce_page_changed), self);

	gtk_spin_button_set_value (priv->rate, (gdouble) nm_setting_wireless_get_rate (setting));
	gtk_spin_button_set_value (priv->tx_power, (gdouble) nm_setting_wireless_get_tx_power (setting));
	gtk_spin_button_set_value (priv->mtu, (gdouble) nm_setting_wireless_get_mtu (setting));
}
예제 #11
0
gboolean
_ostree_static_delta_part_open (GInputStream   *part_in,
                                GBytes         *inline_part_bytes,
                                OstreeStaticDeltaOpenFlags flags,
                                const char     *expected_checksum,
                                GVariant    **out_part,
                                GCancellable *cancellable,
                                GError      **error)
{
  const gboolean trusted = (flags & OSTREE_STATIC_DELTA_OPEN_FLAGS_VARIANT_TRUSTED) > 0;
  const gboolean skip_checksum = (flags & OSTREE_STATIC_DELTA_OPEN_FLAGS_SKIP_CHECKSUM) > 0;
  gsize bytes_read;
  guint8 comptype;
  g_autoptr(GChecksum) checksum = NULL;
  g_autoptr(GInputStream) checksum_in = NULL;
  GInputStream *source_in;

  /* We either take a fd or a GBytes reference */
  g_return_val_if_fail (G_IS_FILE_DESCRIPTOR_BASED (part_in) || inline_part_bytes != NULL, FALSE);
  g_return_val_if_fail (skip_checksum || expected_checksum != NULL, FALSE);

  if (!skip_checksum)
    {
      checksum = g_checksum_new (G_CHECKSUM_SHA256);
      checksum_in = (GInputStream*)ostree_checksum_input_stream_new (part_in, checksum);
      source_in = checksum_in;
    }
  else
    {
      source_in = part_in;
    }

  { guint8 buf[1];
    /* First byte is compression type */
    if (!g_input_stream_read_all (source_in, buf, sizeof(buf), &bytes_read,
                                  cancellable, error))
      return glnx_prefix_error (error, "Reading initial compression flag byte");
    comptype = buf[0];
  }

  g_autoptr(GVariant) ret_part = NULL;
  switch (comptype)
    {
    case 0:
      if (!inline_part_bytes)
        {
          int part_fd = g_file_descriptor_based_get_fd ((GFileDescriptorBased*)part_in);

          /* No compression, no checksums - a fast path */
          if (!ot_util_variant_map_fd (part_fd, 1, G_VARIANT_TYPE (OSTREE_STATIC_DELTA_PART_PAYLOAD_FORMAT_V0),
                                       trusted, &ret_part, error))
            return FALSE;
        }
      else
        {
          g_autoptr(GBytes) content_bytes = g_bytes_new_from_bytes (inline_part_bytes, 1,
                                                                    g_bytes_get_size (inline_part_bytes) - 1);
          ret_part = g_variant_new_from_bytes (G_VARIANT_TYPE (OSTREE_STATIC_DELTA_PART_PAYLOAD_FORMAT_V0),
                                               content_bytes, trusted);
          g_variant_ref_sink (ret_part);
        }

      if (!skip_checksum)
        g_checksum_update (checksum, g_variant_get_data (ret_part),
                           g_variant_get_size (ret_part));

      break;
    case 'x':
      {
        g_autoptr(GConverter) decomp = (GConverter*) _ostree_lzma_decompressor_new ();
        g_autoptr(GInputStream) convin = g_converter_input_stream_new (source_in, decomp);
        g_autoptr(GBytes) buf = ot_map_anonymous_tmpfile_from_content (convin, cancellable, error);
        if (!buf)
          return FALSE;

        ret_part = g_variant_new_from_bytes (G_VARIANT_TYPE (OSTREE_STATIC_DELTA_PART_PAYLOAD_FORMAT_V0),
                                             buf, FALSE);
      }
      break;
    default:
      return glnx_throw (error, "Invalid compression type '%u'", comptype);
    }

  if (checksum)
    {
      const char *actual_checksum = g_checksum_get_string (checksum);
      g_assert (expected_checksum != NULL);
      if (strcmp (actual_checksum, expected_checksum) != 0)
        return glnx_throw (error, "Checksum mismatch in static delta part; expected=%s actual=%s",
                           expected_checksum, actual_checksum);
    }

  *out_part = g_steal_pointer (&ret_part);
  return TRUE;
}
예제 #12
0
/**
 * cockpit_web_response_file:
 * @response: the response
 * @path: escaped path, or NULL to get from response
 * @roots: directories to look for file in
 *
 * Serve a file from disk as an HTTP response.
 */
void
cockpit_web_response_file (CockpitWebResponse *response,
                           const gchar *escaped,
                           gboolean cache_forever,
                           const gchar **roots)
{
  const gchar *cache_control;
  GError *error = NULL;
  gchar *unescaped;
  char *path = NULL;
  gchar *built = NULL;
  GMappedFile *file = NULL;
  const gchar *root;
  GBytes *body;

  g_return_if_fail (COCKPIT_IS_WEB_RESPONSE (response));

  if (!escaped)
    escaped = cockpit_web_response_get_path (response);

  g_return_if_fail (escaped != NULL);

again:
  root = *(roots++);
  if (root == NULL)
    {
      cockpit_web_response_error (response, 404, NULL, "Not Found");
      goto out;
    }

  unescaped = g_uri_unescape_string (escaped, NULL);
  built = g_build_filename (root, unescaped, NULL);
  g_free (unescaped);

  path = realpath (built, NULL);
  g_free (built);

  if (path == NULL)
    {
      if (errno == ENOENT || errno == ENOTDIR || errno == ELOOP || errno == ENAMETOOLONG)
        {
          g_debug ("%s: file not found in root: %s", escaped, root);
          goto again;
        }
      else if (errno == EACCES)
        {
          cockpit_web_response_error (response, 403, NULL, "Access Denied");
          goto out;
        }
      else
        {
          g_warning ("%s: resolving path failed: %m", escaped);
          cockpit_web_response_error (response, 500, NULL, "Internal Server Error");
          goto out;
        }
    }

  /* Double check that realpath() did the right thing */
  g_return_if_fail (strstr (path, "../") == NULL);
  g_return_if_fail (!g_str_has_suffix (path, "/.."));

  /* Someone is trying to escape the root directory */
  if (!path_has_prefix (path, root) &&
      !path_has_prefix (path, cockpit_web_exception_escape_root))
    {
      g_debug ("%s: request tried to escape the root directory: %s: %s", escaped, root, path);
      cockpit_web_response_error (response, 404, NULL, "Not Found");
      goto out;
    }

  if (g_file_test (path, G_FILE_TEST_IS_DIR))
    {
      cockpit_web_response_error (response, 403, NULL, "Directory Listing Denied");
      goto out;
    }

  file = g_mapped_file_new (path, FALSE, &error);
  if (file == NULL)
    {
      if (g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_PERM) ||
          g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_ACCES) ||
          g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_ISDIR))
        {
          cockpit_web_response_error (response, 403, NULL, "Access denied");
          g_clear_error (&error);
          goto out;
        }
      else
        {
          g_warning ("%s: %s", path, error->message);
          cockpit_web_response_error (response, 500, NULL, "Internal server error");
          g_clear_error (&error);
          goto out;
        }
    }

  body = g_mapped_file_get_bytes (file);

  cache_control = cache_forever ? "max-age=31556926, public" : NULL;
  cockpit_web_response_headers (response, 200, "OK", g_bytes_get_size (body),
                                "Cache-Control", cache_control,
                                NULL);

  if (cockpit_web_response_queue (response, body))
    cockpit_web_response_complete (response);

  g_bytes_unref (body);

out:
  free (path);
  if (file)
    g_mapped_file_unref (file);
}
/**
 * gs_plugin_file_to_app:
 */
gboolean
gs_plugin_file_to_app (GsPlugin *plugin,
		       GList **list,
		       GFile *file,
		       GCancellable *cancellable,
		       GError **error)
{
	g_autofree gchar *content_type = NULL;
	g_autofree gchar *id_prefixed = NULL;
	g_autoptr(GBytes) appstream_gz = NULL;
	g_autoptr(GBytes) icon_data = NULL;
	g_autoptr(GBytes) metadata = NULL;
	g_autoptr(GsApp) app = NULL;
	g_autoptr(XdgAppBundleRef) xref_bundle = NULL;
	const gchar *mimetypes[] = {
		"application/vnd.xdgapp",
		NULL };

	/* does this match any of the mimetypes we support */
	content_type = gs_utils_get_content_type (file, cancellable, error);
	if (content_type == NULL)
		return FALSE;
	if (!g_strv_contains (mimetypes, content_type))
		return TRUE;

	/* load bundle */
	xref_bundle = xdg_app_bundle_ref_new (file, error);
	if (xref_bundle == NULL) {
		g_prefix_error (error, "error loading bundle: ");
		return FALSE;
	}

	/* create a virtual ID */
	id_prefixed = gs_plugin_xdg_app_build_id (XDG_APP_REF (xref_bundle));

	/* load metadata */
	app = gs_app_new (id_prefixed);
	gs_app_set_kind (app, AS_APP_KIND_DESKTOP);
	gs_app_set_state (app, AS_APP_STATE_AVAILABLE_LOCAL);
	gs_app_set_size_installed (app, xdg_app_bundle_ref_get_installed_size (xref_bundle));
	gs_plugin_xdg_app_set_metadata (app, XDG_APP_REF (xref_bundle));
	metadata = xdg_app_bundle_ref_get_metadata (xref_bundle);
	if (!gs_plugin_xdg_app_set_app_metadata (app,
						 g_bytes_get_data (metadata, NULL),
						 g_bytes_get_size (metadata),
						 error))
		return FALSE;

	/* load AppStream */
	appstream_gz = xdg_app_bundle_ref_get_appstream (xref_bundle);
	if (appstream_gz != NULL) {
		g_autoptr(GZlibDecompressor) decompressor = NULL;
		g_autoptr(GInputStream) stream_gz = NULL;
		g_autoptr(GInputStream) stream_data = NULL;
		g_autoptr(GBytes) appstream = NULL;
		g_autoptr(AsStore) store = NULL;
		g_autofree gchar *id = NULL;
		AsApp *item;

		/* decompress data */
		decompressor = g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP);
		stream_gz = g_memory_input_stream_new_from_bytes (appstream_gz);
		if (stream_gz == NULL)
			return FALSE;
		stream_data = g_converter_input_stream_new (stream_gz,
							    G_CONVERTER (decompressor));

		appstream = g_input_stream_read_bytes (stream_data,
						       0x100000, /* 1Mb */
						       cancellable,
						       error);
		if (appstream == NULL)
			return FALSE;
		store = as_store_new ();
		if (!as_store_from_bytes (store, appstream, cancellable, error))
			return FALSE;

		/* find app */
		id = g_strdup_printf ("%s.desktop", gs_app_get_xdgapp_name (app));
		item = as_store_get_app_by_id (store, id);
		if (item == NULL) {
			g_set_error (error,
				     GS_PLUGIN_ERROR,
				     GS_PLUGIN_ERROR_FAILED,
				     "application %s not found",
				     id);
			return FALSE;
		}

		/* copy details from AppStream to app */
		if (!gs_appstream_refine_app (plugin, app, item, error))
			return FALSE;
	}

	/* load icon */
	icon_data = xdg_app_bundle_ref_get_icon (xref_bundle,
						 64 * gs_plugin_get_scale (plugin));
	if (icon_data == NULL)
		icon_data = xdg_app_bundle_ref_get_icon (xref_bundle, 64);
	if (icon_data != NULL) {
		g_autoptr(GInputStream) stream_icon = NULL;
		g_autoptr(GdkPixbuf) pixbuf = NULL;
		stream_icon = g_memory_input_stream_new_from_bytes (icon_data);
		pixbuf = gdk_pixbuf_new_from_stream (stream_icon, cancellable, error);
		if (pixbuf == NULL)
			return FALSE;
		gs_app_set_pixbuf (app, pixbuf);
	} else {
		g_autoptr(AsIcon) icon = NULL;
		icon = as_icon_new ();
		as_icon_set_kind (icon, AS_ICON_KIND_STOCK);
		as_icon_set_name (icon, "application-x-executable");
		gs_app_set_icon (app, icon);
	}

	/* not quite true: this just means we can update this specific app */
	if (xdg_app_bundle_ref_get_origin (xref_bundle))
		gs_app_add_quirk (app, AS_APP_QUIRK_HAS_SOURCE);

	g_debug ("created local app: %s", gs_app_to_string (app));
	gs_app_list_add (list, app);
	return TRUE;
}
예제 #14
0
static void
create_trust_file_for_issuer_and_serial (const gchar *filename, const gchar *certificate)
{
	GError *err = NULL;
	GNode *asn, *cert, *choice, *ref;
	GNode *issuer, *serial;
	gchar *data;
	GBytes *result;
	GBytes *value;
	GBytes *element;
	gsize n_data;
	GBytes *bytes;

	if (!g_file_get_contents (certificate, &data, &n_data, &err))
		barf_and_die ("couldn't read certificate file", egg_error_message (err));

	/* Make sure the certificate is */
	cert = egg_asn1x_create (pkix_asn1_tab, "Certificate");
	g_return_if_fail (cert);

	bytes = g_bytes_new_take (data, n_data);
	if (!egg_asn1x_decode (cert, bytes))
		barf_and_die ("couldn't parse der certificate file", egg_asn1x_message (cert));
	g_bytes_unref (bytes);

	/* Dig out the issuer and serial */
	issuer = egg_asn1x_node (cert, "tbsCertificate", "issuer", NULL);
	serial = egg_asn1x_node (cert, "tbsCertificate", "serialNumber", NULL);
	g_return_if_fail (issuer && serial);

	/* Create up the trust structure */
	asn = egg_asn1x_create (xdg_asn1_tab, "trust-1");
	g_return_if_fail (asn);

	/* Setup the type of trust assertion */
	ref = egg_asn1x_node (asn, "reference", NULL);
	choice = egg_asn1x_node (ref, "certReference", NULL);
	if (!egg_asn1x_set_choice (ref, choice))
		g_return_if_reached ();

	/* Copy over the serial and issuer */
	element = egg_asn1x_get_element_raw (issuer);
	if (!egg_asn1x_set_any_raw (egg_asn1x_node (choice, "issuer", NULL), element))
		g_return_if_reached ();
	g_bytes_unref (element);

	value = egg_asn1x_get_integer_as_raw (serial);
	egg_asn1x_set_integer_as_raw (egg_asn1x_node (choice, "serialNumber", NULL), value);
	g_bytes_unref (value);

	result = egg_asn1x_encode (asn, NULL);
	if (result == NULL)
		barf_and_die ("couldn't encode the trust file", egg_asn1x_message (asn));

	g_free (data);
	egg_asn1x_destroy (cert);
	egg_asn1x_destroy (asn);

	if (!g_file_set_contents (filename, g_bytes_get_data (result, NULL),
	                          g_bytes_get_size (result), &err))
		barf_and_die ("couldn't write trust file", egg_error_message (err));

	g_bytes_unref (result);
}
예제 #15
0
/**
 * cockpit_web_response_file:
 * @response: the response
 * @path: escaped path, or NULL to get from response
 * @roots: directories to look for file in
 *
 * Serve a file from disk as an HTTP response.
 */
void
cockpit_web_response_file (CockpitWebResponse *response,
                           const gchar *escaped,
                           const gchar **roots)
{
  const gchar *csp_header;
  GError *error = NULL;
  gchar *unescaped = NULL;
  gchar *path = NULL;
  GMappedFile *file = NULL;
  const gchar *root;
  GBytes *body;

  g_return_if_fail (COCKPIT_IS_WEB_RESPONSE (response));

  if (!escaped)
    escaped = cockpit_web_response_get_path (response);

  g_return_if_fail (escaped != NULL);

  /* Someone is trying to escape the root directory, or access hidden files? */
  unescaped = g_uri_unescape_string (escaped, NULL);
  if (strstr (unescaped, "/.") || strstr (unescaped, "../") || strstr (unescaped, "//"))
    {
      g_debug ("%s: invalid path request", escaped);
      cockpit_web_response_error (response, 404, NULL, "Not Found");
      goto out;
    }

again:
  root = *(roots++);
  if (root == NULL)
    {
      cockpit_web_response_error (response, 404, NULL, "Not Found");
      goto out;
    }

  g_free (path);
  path = g_build_filename (root, unescaped, NULL);

  if (g_file_test (path, G_FILE_TEST_IS_DIR))
    {
      cockpit_web_response_error (response, 403, NULL, "Directory Listing Denied");
      goto out;
    }

  /* As a double check of above behavior */
  g_assert (path_has_prefix (path, root));

  g_clear_error (&error);
  file = g_mapped_file_new (path, FALSE, &error);
  if (file == NULL)
    {
      if (g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT) ||
          g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NAMETOOLONG))
        {
          g_debug ("%s: file not found in root: %s", escaped, root);
          goto again;
        }
      else if (g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_PERM) ||
               g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_ACCES) ||
               g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_ISDIR))
        {
          cockpit_web_response_error (response, 403, NULL, "Access denied");
          goto out;
        }
      else
        {
          g_warning ("%s: %s", path, error->message);
          cockpit_web_response_error (response, 500, NULL, "Internal server error");
          goto out;
        }
    }

  body = g_mapped_file_get_bytes (file);

  /*
   * The default Content-Security-Policy for .html files allows
   * the site to have inline <script> and <style> tags. This code
   * is not used when serving resources once logged in, only for
   * static resources when we don't yet have a session.
   */

  csp_header = NULL;
  if (g_str_has_suffix (unescaped, ".html"))
    csp_header = "Content-Security-Policy";

  cockpit_web_response_headers (response, 200, "OK", g_bytes_get_size (body),
                                csp_header, "default-src 'self' 'unsafe-inline'; connect-src 'self' ws: wss:",
                                NULL);

  if (cockpit_web_response_queue (response, body))
    cockpit_web_response_complete (response);

  g_bytes_unref (body);

out:
  g_free (unescaped);
  g_clear_error (&error);
  g_free (path);
  if (file)
    g_mapped_file_unref (file);
}
gboolean
nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self,
                                        NMSetting8021x *setting,
                                        const char *con_uuid,
                                        gboolean wired)
{
	NMSupplicantConfigPrivate *priv;
	char *tmp;
	const char *peapver, *value, *path;
	gboolean success, added;
	GString *phase1, *phase2;
	GBytes *bytes;
	gboolean fast = FALSE;
	guint32 i, num_eap;
	gboolean fast_provisoning_allowed = FALSE;

	g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), FALSE);
	g_return_val_if_fail (setting != NULL, FALSE);
	g_return_val_if_fail (con_uuid != NULL, FALSE);

	priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self);

	value = nm_setting_802_1x_get_password (setting);
	if (value) {
		if (!add_string_val (self, value, "password", FALSE, TRUE))
			return FALSE;
	} else {
		bytes = nm_setting_802_1x_get_password_raw (setting);
		if (bytes) {
			success = nm_supplicant_config_add_option (self,
			                                           "password",
			                                           (const char *) g_bytes_get_data (bytes, NULL),
			                                           g_bytes_get_size (bytes),
			                                           TRUE);
			if (!success) {
				nm_log_warn (LOGD_SUPPLICANT, "Error adding password-raw to supplicant config.");
				return FALSE;
			}
		}
	}
	value = nm_setting_802_1x_get_pin (setting);
	if (!add_string_val (self, value, "pin", FALSE, TRUE))
		return FALSE;

	if (wired) {
		if (!add_string_val (self, "IEEE8021X", "key_mgmt", FALSE, FALSE))
			return FALSE;
		/* Wired 802.1x must always use eapol_flags=0 */
		if (!add_string_val (self, "0", "eapol_flags", FALSE, FALSE))
			return FALSE;
		nm_supplicant_config_set_ap_scan (self, 0);
	}

	ADD_STRING_LIST_VAL (setting, 802_1x, eap_method, eap_methods, "eap", ' ', TRUE, FALSE);

	/* Check EAP method for special handling: PEAP + GTC, FAST */
	num_eap = nm_setting_802_1x_get_num_eap_methods (setting);
	for (i = 0; i < num_eap; i++) {
		const char *method = nm_setting_802_1x_get_eap_method (setting, i);

		if (method && (strcasecmp (method, "fast") == 0)) {
			fast = TRUE;
			priv->fast_required = TRUE;
		}
	}

	/* Drop the fragment size a bit for better compatibility */
	if (!nm_supplicant_config_add_option (self, "fragment_size", "1300", -1, FALSE))
		return FALSE;

	phase1 = g_string_new (NULL);
	peapver = nm_setting_802_1x_get_phase1_peapver (setting);
	if (peapver) {
		if (!strcmp (peapver, "0"))
			g_string_append (phase1, "peapver=0");
		else if (!strcmp (peapver, "1"))
			g_string_append (phase1, "peapver=1");
	}

	if (nm_setting_802_1x_get_phase1_peaplabel (setting)) {
		if (phase1->len)
			g_string_append_c (phase1, ' ');
		g_string_append_printf (phase1, "peaplabel=%s", nm_setting_802_1x_get_phase1_peaplabel (setting));
	}

	value = nm_setting_802_1x_get_phase1_fast_provisioning (setting);
	if (value) {
		if (phase1->len)
			g_string_append_c (phase1, ' ');
		g_string_append_printf (phase1, "fast_provisioning=%s", value);
		
		if (strcmp (value, "0") != 0)
			fast_provisoning_allowed = TRUE;
	}

	if (phase1->len) {
		if (!add_string_val (self, phase1->str, "phase1", FALSE, FALSE)) {
			g_string_free (phase1, TRUE);
			return FALSE;
		}
	}
	g_string_free (phase1, TRUE);

	phase2 = g_string_new (NULL);
	if (nm_setting_802_1x_get_phase2_auth (setting) && !fast_provisoning_allowed) {
		tmp = g_ascii_strup (nm_setting_802_1x_get_phase2_auth (setting), -1);
		g_string_append_printf (phase2, "auth=%s", tmp);
		g_free (tmp);
	}

	if (nm_setting_802_1x_get_phase2_autheap (setting)) {
		if (phase2->len)
			g_string_append_c (phase2, ' ');
		tmp = g_ascii_strup (nm_setting_802_1x_get_phase2_autheap (setting), -1);
		g_string_append_printf (phase2, "autheap=%s", tmp);
		g_free (tmp);
	}

	if (phase2->len) {
		if (!add_string_val (self, phase2->str, "phase2", FALSE, FALSE)) {
			g_string_free (phase2, TRUE);
			return FALSE;
		}
	}
	g_string_free (phase2, TRUE);

	/* PAC file */
	path = nm_setting_802_1x_get_pac_file (setting);
	if (path) {
		if (!add_string_val (self, path, "pac_file", FALSE, FALSE))
			return FALSE;
	} else {
		/* PAC file is not specified.
		 * If provisioning is allowed, use an blob format.
		 */
		if (fast_provisoning_allowed) {
			char *blob_name = g_strdup_printf ("blob://pac-blob-%s", con_uuid);
			if (!add_string_val (self, blob_name, "pac_file", FALSE, FALSE)) {
				g_free (blob_name);
				return FALSE;
			}
			g_free (blob_name);
		} else {
			/* This is only error for EAP-FAST; don't disturb other methods. */
			if (fast) {
				nm_log_err (LOGD_SUPPLICANT, "EAP-FAST error: no PAC file provided and "
				                              "automatic PAC provisioning is disabled.");
				return FALSE;
			}
		}
	}

	/* CA path */
	path = nm_setting_802_1x_get_ca_path (setting);
	if (nm_setting_802_1x_get_system_ca_certs (setting))
		path = SYSTEM_CA_PATH;
	if (path) {
		if (!add_string_val (self, path, "ca_path", FALSE, FALSE))
			return FALSE;
	}

	/* Phase2 CA path */
	path = nm_setting_802_1x_get_phase2_ca_path (setting);
	if (nm_setting_802_1x_get_system_ca_certs (setting))
		path = SYSTEM_CA_PATH;
	if (path) {
		if (!add_string_val (self, path, "ca_path2", FALSE, FALSE))
			return FALSE;
	}

	/* CA certificate */
	switch (nm_setting_802_1x_get_ca_cert_scheme (setting)) {
	case NM_SETTING_802_1X_CK_SCHEME_BLOB:
		bytes = nm_setting_802_1x_get_ca_cert_blob (setting);
		ADD_BLOB_VAL (bytes, "ca_cert", con_uuid);
		break;
	case NM_SETTING_802_1X_CK_SCHEME_PATH:
		path = nm_setting_802_1x_get_ca_cert_path (setting);
		if (!add_string_val (self, path, "ca_cert", FALSE, FALSE))
			return FALSE;
		break;
	default:
		break;
	}

	/* Phase 2 CA certificate */
	switch (nm_setting_802_1x_get_phase2_ca_cert_scheme (setting)) {
	case NM_SETTING_802_1X_CK_SCHEME_BLOB:
		bytes = nm_setting_802_1x_get_phase2_ca_cert_blob (setting);
		ADD_BLOB_VAL (bytes, "ca_cert2", con_uuid);
		break;
	case NM_SETTING_802_1X_CK_SCHEME_PATH:
		path = nm_setting_802_1x_get_phase2_ca_cert_path (setting);
		if (!add_string_val (self, path, "ca_cert2", FALSE, FALSE))
			return FALSE;
		break;
	default:
		break;
	}

	/* Subject match */
	value = nm_setting_802_1x_get_subject_match (setting);
	if (!add_string_val (self, value, "subject_match", FALSE, FALSE))
		return FALSE;
	value = nm_setting_802_1x_get_phase2_subject_match (setting);
	if (!add_string_val (self, value, "subject_match2", FALSE, FALSE))
		return FALSE;

	/* altSubjectName match */
	ADD_STRING_LIST_VAL (setting, 802_1x, altsubject_match, altsubject_matches, "altsubject_match", ';', FALSE, FALSE);
	ADD_STRING_LIST_VAL (setting, 802_1x, phase2_altsubject_match, phase2_altsubject_matches, "altsubject_match2", ';', FALSE, FALSE);

	/* Private key */
	added = FALSE;
	switch (nm_setting_802_1x_get_private_key_scheme (setting)) {
	case NM_SETTING_802_1X_CK_SCHEME_BLOB:
		bytes = nm_setting_802_1x_get_private_key_blob (setting);
		ADD_BLOB_VAL (bytes, "private_key", con_uuid);
		added = TRUE;
		break;
	case NM_SETTING_802_1X_CK_SCHEME_PATH:
		path = nm_setting_802_1x_get_private_key_path (setting);
		if (!add_string_val (self, path, "private_key", FALSE, FALSE))
			return FALSE;
		added = TRUE;
		break;
	default:
		break;
	}

	if (added) {
		NMSetting8021xCKFormat format;
		NMSetting8021xCKScheme scheme;

		format = nm_setting_802_1x_get_private_key_format (setting);
		scheme = nm_setting_802_1x_get_private_key_scheme (setting);

		if (   scheme == NM_SETTING_802_1X_CK_SCHEME_PATH
		    || format == NM_SETTING_802_1X_CK_FORMAT_PKCS12) {
			/* Only add the private key password for PKCS#12 blobs and
			 * all path schemes, since in both of these cases the private key
			 * isn't decrypted at all.
			 */
			value = nm_setting_802_1x_get_private_key_password (setting);
			if (!add_string_val (self, value, "private_key_passwd", FALSE, TRUE))
				return FALSE;
		}

		if (format != NM_SETTING_802_1X_CK_FORMAT_PKCS12) {
			/* Only add the client cert if the private key is not PKCS#12, as
			 * wpa_supplicant configuration directs us to do.
			 */
			switch (nm_setting_802_1x_get_client_cert_scheme (setting)) {
			case NM_SETTING_802_1X_CK_SCHEME_BLOB:
				bytes = nm_setting_802_1x_get_client_cert_blob (setting);
				ADD_BLOB_VAL (bytes, "client_cert", con_uuid);
				break;
			case NM_SETTING_802_1X_CK_SCHEME_PATH:
				path = nm_setting_802_1x_get_client_cert_path (setting);
				if (!add_string_val (self, path, "client_cert", FALSE, FALSE))
					return FALSE;
				break;
			default:
				break;
			}
		}
	}

	/* Phase 2 private key */
	added = FALSE;
	switch (nm_setting_802_1x_get_phase2_private_key_scheme (setting)) {
	case NM_SETTING_802_1X_CK_SCHEME_BLOB:
		bytes = nm_setting_802_1x_get_phase2_private_key_blob (setting);
		ADD_BLOB_VAL (bytes, "private_key2", con_uuid);
		added = TRUE;
		break;
	case NM_SETTING_802_1X_CK_SCHEME_PATH:
		path = nm_setting_802_1x_get_phase2_private_key_path (setting);
		if (!add_string_val (self, path, "private_key2", FALSE, FALSE))
			return FALSE;
		added = TRUE;
		break;
	default:
		break;
	}

	if (added) {
		NMSetting8021xCKFormat format;
		NMSetting8021xCKScheme scheme;

		format = nm_setting_802_1x_get_phase2_private_key_format (setting);
		scheme = nm_setting_802_1x_get_phase2_private_key_scheme (setting);

		if (   scheme == NM_SETTING_802_1X_CK_SCHEME_PATH
		    || format == NM_SETTING_802_1X_CK_FORMAT_PKCS12) {
			/* Only add the private key password for PKCS#12 blobs and
			 * all path schemes, since in both of these cases the private key
			 * isn't decrypted at all.
			 */
			value = nm_setting_802_1x_get_phase2_private_key_password (setting);
			if (!add_string_val (self, value, "private_key2_passwd", FALSE, TRUE))
				return FALSE;
		}

		if (format != NM_SETTING_802_1X_CK_FORMAT_PKCS12) {
			/* Only add the client cert if the private key is not PKCS#12, as
			 * wpa_supplicant configuration directs us to do.
			 */
			switch (nm_setting_802_1x_get_phase2_client_cert_scheme (setting)) {
			case NM_SETTING_802_1X_CK_SCHEME_BLOB:
				bytes = nm_setting_802_1x_get_phase2_client_cert_blob (setting);
				ADD_BLOB_VAL (bytes, "client_cert2", con_uuid);
				break;
			case NM_SETTING_802_1X_CK_SCHEME_PATH:
				path = nm_setting_802_1x_get_phase2_client_cert_path (setting);
				if (!add_string_val (self, path, "client_cert2", FALSE, FALSE))
					return FALSE;
				break;
			default:
				break;
			}
		}
	}

	value = nm_setting_802_1x_get_identity (setting);
	if (!add_string_val (self, value, "identity", FALSE, FALSE))
		return FALSE;
	value = nm_setting_802_1x_get_anonymous_identity (setting);
	if (!add_string_val (self, value, "anonymous_identity", FALSE, FALSE))
		return FALSE;

	return TRUE;
}
예제 #17
0
파일: css_pixbufs.c 프로젝트: GYGit/gtk
GtkWidget *
do_css_pixbufs (GtkWidget *do_widget)
{
  static GtkWidget *window = NULL;

  if (!window)
    {
      GtkWidget *paned, *container, *child;
      GtkStyleProvider *provider;
      GtkTextBuffer *text;
      GBytes *bytes;

      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
      gtk_window_set_title (GTK_WINDOW (window), "Animated Backgrounds");
      gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (do_widget));
      gtk_window_set_default_size (GTK_WINDOW (window), 400, 300);
      g_signal_connect (window, "destroy",
                        G_CALLBACK (gtk_widget_destroyed), &window);

      paned = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
      gtk_container_add (GTK_CONTAINER (window), paned);

      /* Need a filler so we get a handle */
      child = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
      gtk_container_add (GTK_CONTAINER (paned), child);

      text = gtk_text_buffer_new (NULL);
      gtk_text_buffer_create_tag (text,
                                  "warning",
                                  "underline", PANGO_UNDERLINE_SINGLE,
                                  NULL);
      gtk_text_buffer_create_tag (text,
                                  "error",
                                  "underline", PANGO_UNDERLINE_ERROR,
                                  NULL);

      provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());

      container = gtk_scrolled_window_new (NULL, NULL);
      gtk_container_add (GTK_CONTAINER (paned), container);
      child = gtk_text_view_new_with_buffer (text);
      gtk_container_add (GTK_CONTAINER (container), child);
      g_signal_connect (text, "changed",
                        G_CALLBACK (css_text_changed), provider);

      bytes = g_resources_lookup_data ("/css_pixbufs/gtk.css", 0, NULL);
      gtk_text_buffer_set_text (text, g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes));
      g_bytes_unref (bytes);

      g_signal_connect (provider,
                        "parsing-error",
                        G_CALLBACK (show_parsing_error),
                        gtk_text_view_get_buffer (GTK_TEXT_VIEW (child)));

      apply_css (window, provider);
    }

  if (!gtk_widget_get_visible (window))
    gtk_widget_show_all (window);
  else
    gtk_widget_destroy (window);

  return window;
}
예제 #18
0
static gboolean
realm_join_as_owner (UmRealmObject *realm,
                     const gchar *owner,
                     const gchar *login,
                     const gchar *password,
                     GBytes *credentials,
                     GCancellable *cancellable,
                     GAsyncReadyCallback callback,
                     gpointer user_data)
{
        UmRealmKerberosMembership *membership;
        GSimpleAsyncResult *async;
        GVariant *contents;
        GVariant *options;
        GVariant *option;
        GVariant *creds;
        const gchar *type;

        membership = um_realm_object_get_kerberos_membership (realm);
        g_return_val_if_fail (membership != NULL, FALSE);

        type = find_supported_credentials (membership, owner);
        if (type == NULL) {
                g_debug ("Couldn't find supported credential type for owner: %s", owner);
                g_object_unref (membership);
                return FALSE;
        }

        async = g_simple_async_result_new (G_OBJECT (realm), callback, user_data,
                                           realm_join_as_owner);

        if (g_str_equal (type, "ccache")) {
                g_debug ("Using a kerberos credential cache to join the realm");
                contents = g_variant_new_from_data (G_VARIANT_TYPE ("ay"),
                                                    g_bytes_get_data (credentials, NULL),
                                                    g_bytes_get_size (credentials),
                                                    TRUE, (GDestroyNotify)g_bytes_unref, credentials);

        } else if (g_str_equal (type, "password")) {
                g_debug ("Using a user/password to join the realm");
                contents = g_variant_new ("(ss)", login, password);

        } else {
                g_assert_not_reached ();
        }

        creds = g_variant_new ("(ssv)", type, owner, contents);
        option = g_variant_new ("{sv}", "manage-system", g_variant_new_boolean (FALSE));
        options = g_variant_new_array (G_VARIANT_TYPE ("{sv}"), &option, 1);

        g_debug ("Calling the Join() method with %s credentials", owner);

        um_realm_kerberos_membership_call_join (membership, creds, options,
                                                cancellable, on_realm_join_complete,
                                                g_object_ref (async));

        g_object_unref (async);
        g_object_unref (membership);

        return TRUE;
}
예제 #19
0
gboolean
nm_supplicant_config_add_setting_wireless (NMSupplicantConfig * self,
                                           NMSettingWireless * setting,
                                           guint32 fixed_freq,
                                           GError **error)
{
	NMSupplicantConfigPrivate *priv;
	gboolean is_adhoc, is_ap;
	const char *mode, *band;
	guint32 channel;
	GBytes *ssid;
	const char *bssid;

	g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), FALSE);
	g_return_val_if_fail (setting != NULL, FALSE);
	g_return_val_if_fail (!error || !*error, FALSE);

	priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self);

	mode = nm_setting_wireless_get_mode (setting);
	is_adhoc = (mode && !strcmp (mode, "adhoc")) ? TRUE : FALSE;
	is_ap = (mode && !strcmp (mode, "ap")) ? TRUE : FALSE;
	if (is_adhoc || is_ap)
		priv->ap_scan = 2;
	else
		priv->ap_scan = 1;

	ssid = nm_setting_wireless_get_ssid (setting);
	if (!nm_supplicant_config_add_option (self, "ssid",
	                                      (char *) g_bytes_get_data (ssid, NULL),
	                                      g_bytes_get_size (ssid),
	                                      FALSE,
	                                      error))
		return FALSE;

	if (is_adhoc) {
		if (!nm_supplicant_config_add_option (self, "mode", "1", -1, FALSE, error))
			return FALSE;
	}

	if (is_ap) {
		if (!nm_supplicant_config_add_option (self, "mode", "2", -1, FALSE, error))
			return FALSE;
	}

	if ((is_adhoc || is_ap) && fixed_freq) {
		gs_free char *str_freq = NULL;

		str_freq = g_strdup_printf ("%u", fixed_freq);
		if (!nm_supplicant_config_add_option (self, "frequency", str_freq, -1, FALSE, error))
			return FALSE;
	}

	/* Except for Ad-Hoc and Hotspot, request that the driver probe for the
	 * specific SSID we want to associate with.
	 */
	if (!(is_adhoc || is_ap)) {
		if (!nm_supplicant_config_add_option (self, "scan_ssid", "1", -1, FALSE, error))
			return FALSE;
	}

	bssid = nm_setting_wireless_get_bssid (setting);
	if (bssid) {
		if (!nm_supplicant_config_add_option (self, "bssid",
		                                      bssid, strlen (bssid),
		                                      FALSE,
		                                      error))
			return FALSE;
	}

	band = nm_setting_wireless_get_band (setting);
	channel = nm_setting_wireless_get_channel (setting);
	if (band) {
		if (channel) {
			guint32 freq;
			gs_free char *str_freq = NULL;

			freq = nm_utils_wifi_channel_to_freq (channel, band);
			str_freq = g_strdup_printf ("%u", freq);
			if (!nm_supplicant_config_add_option (self, "freq_list", str_freq, -1, FALSE, error))
				return FALSE;
		} else {
			const char *freqs = NULL;

			if (!strcmp (band, "a"))
				freqs = wifi_freqs_to_string (FALSE);
			else if (!strcmp (band, "bg"))
				freqs = wifi_freqs_to_string (TRUE);

			if (freqs && !nm_supplicant_config_add_option (self, "freq_list", freqs, strlen (freqs), FALSE, error))
				return FALSE;
		}
	}

	return TRUE;
}
예제 #20
0
파일: main.c 프로젝트: Distrotech/gtk
static void
add_data_tab (const gchar *demoname)
{
  gchar *resource_dir, *resource_name;
  gchar **resources;
  GtkWidget *widget, *label;
  guint i;

  resource_dir = g_strconcat ("/", demoname, NULL);
  resources = g_resources_enumerate_children (resource_dir, 0, NULL);
  if (resources == NULL)
    {
      g_free (resource_dir);
      return;
    }

  for (i = 0; resources[i]; i++)
    {
      resource_name = g_strconcat (resource_dir, "/", resources[i], NULL);

      widget = gtk_image_new_from_resource (resource_name);
      if (gtk_image_get_pixbuf (GTK_IMAGE (widget)) == NULL &&
          gtk_image_get_animation (GTK_IMAGE (widget)) == NULL)
        {
          GBytes *bytes;

          /* So we've used the best API available to figure out it's
           * not an image. Let's try something else then.
           */
          g_object_ref_sink (widget);
          g_object_unref (widget);

          bytes = g_resources_lookup_data (resource_name, 0, NULL);
          g_assert (bytes);

          if (g_utf8_validate (g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes), NULL))
            {
              /* Looks like it parses as text. Dump it into a textview then! */
              GtkTextBuffer *buffer;
              GtkWidget *textview;

              widget = create_text (&textview, FALSE);
              buffer = gtk_text_buffer_new (NULL);
              gtk_text_buffer_set_text (buffer, g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes));
              gtk_text_view_set_buffer (GTK_TEXT_VIEW (textview), buffer);
            }
          else
            {
              g_warning ("Don't know how to display resource '%s'\n", resource_name);
              widget = NULL;
            }

          g_bytes_unref (bytes);
        }

      gtk_widget_show_all (widget);
      label = gtk_label_new (resources[i]);
      gtk_widget_show (label);
      gtk_notebook_append_page (GTK_NOTEBOOK (notebook), widget, label);
      gtk_container_child_set (GTK_CONTAINER (notebook),
                               GTK_WIDGET (widget),
                               "tab-expand", TRUE,
                               NULL);

      g_free (resource_name);
    }

  g_strfreev (resources);
  g_free (resource_dir);
}
예제 #21
0
gboolean
nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self,
                                        NMSetting8021x *setting,
                                        const char *con_uuid,
                                        guint32 mtu,
                                        gboolean wired,
                                        GError **error)
{
	NMSupplicantConfigPrivate *priv;
	char *tmp;
	const char *peapver, *value, *path;
	gboolean added;
	GString *phase1, *phase2;
	GBytes *bytes;
	gboolean fast = FALSE;
	guint32 i, num_eap;
	gboolean fast_provisoning_allowed = FALSE;
	const char *ca_path_override = NULL, *ca_cert_override = NULL;
	guint32 frag, hdrs;
	gs_free char *frag_str = NULL;

	g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), FALSE);
	g_return_val_if_fail (setting != NULL, FALSE);
	g_return_val_if_fail (con_uuid != NULL, FALSE);

	priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self);

	value = nm_setting_802_1x_get_password (setting);
	if (value) {
		if (!add_string_val (self, value, "password", FALSE, TRUE, error))
			return FALSE;
	} else {
		bytes = nm_setting_802_1x_get_password_raw (setting);
		if (bytes) {
			if (!nm_supplicant_config_add_option (self,
			                                      "password",
			                                      (const char *) g_bytes_get_data (bytes, NULL),
			                                      g_bytes_get_size (bytes),
			                                      TRUE,
			                                      error))
				return FALSE;
		}
	}
	value = nm_setting_802_1x_get_pin (setting);
	if (!add_string_val (self, value, "pin", FALSE, TRUE, error))
		return FALSE;

	if (wired) {
		if (!add_string_val (self, "IEEE8021X", "key_mgmt", FALSE, FALSE, error))
			return FALSE;
		/* Wired 802.1x must always use eapol_flags=0 */
		if (!add_string_val (self, "0", "eapol_flags", FALSE, FALSE, error))
			return FALSE;
		priv->ap_scan = 0;
	}

	if (!ADD_STRING_LIST_VAL (self, setting, 802_1x, eap_method, eap_methods, "eap", ' ', TRUE, FALSE, error))
		return FALSE;

	/* Check EAP method for special handling: PEAP + GTC, FAST */
	num_eap = nm_setting_802_1x_get_num_eap_methods (setting);
	for (i = 0; i < num_eap; i++) {
		const char *method = nm_setting_802_1x_get_eap_method (setting, i);

		if (method && (strcasecmp (method, "fast") == 0)) {
			fast = TRUE;
			priv->fast_required = TRUE;
		}
	}

	/* Adjust the fragment size according to MTU, but do not set it higher than 1280-14
	 * for better compatibility */
	hdrs = 14; /* EAPOL + EAP-TLS */
	frag = 1280 - hdrs;
	if (mtu > hdrs)
		frag = CLAMP (mtu - hdrs, 100, frag);
	frag_str = g_strdup_printf ("%u", frag);

	if (!nm_supplicant_config_add_option (self, "fragment_size", frag_str, -1, FALSE, error))
		return FALSE;

	phase1 = g_string_new (NULL);
	peapver = nm_setting_802_1x_get_phase1_peapver (setting);
	if (peapver) {
		if (!strcmp (peapver, "0"))
			g_string_append (phase1, "peapver=0");
		else if (!strcmp (peapver, "1"))
			g_string_append (phase1, "peapver=1");
	}

	if (nm_setting_802_1x_get_phase1_peaplabel (setting)) {
		if (phase1->len)
			g_string_append_c (phase1, ' ');
		g_string_append_printf (phase1, "peaplabel=%s", nm_setting_802_1x_get_phase1_peaplabel (setting));
	}

	value = nm_setting_802_1x_get_phase1_fast_provisioning (setting);
	if (value) {
		if (phase1->len)
			g_string_append_c (phase1, ' ');
		g_string_append_printf (phase1, "fast_provisioning=%s", value);

		if (strcmp (value, "0") != 0)
			fast_provisoning_allowed = TRUE;
	}

	if (phase1->len) {
		if (!add_string_val (self, phase1->str, "phase1", FALSE, FALSE, error)) {
			g_string_free (phase1, TRUE);
			return FALSE;
		}
	}
	g_string_free (phase1, TRUE);

	phase2 = g_string_new (NULL);
	if (nm_setting_802_1x_get_phase2_auth (setting) && !fast_provisoning_allowed) {
		tmp = g_ascii_strup (nm_setting_802_1x_get_phase2_auth (setting), -1);
		g_string_append_printf (phase2, "auth=%s", tmp);
		g_free (tmp);
	}

	if (nm_setting_802_1x_get_phase2_autheap (setting)) {
		if (phase2->len)
			g_string_append_c (phase2, ' ');
		tmp = g_ascii_strup (nm_setting_802_1x_get_phase2_autheap (setting), -1);
		g_string_append_printf (phase2, "autheap=%s", tmp);
		g_free (tmp);
	}

	if (phase2->len) {
		if (!add_string_val (self, phase2->str, "phase2", FALSE, FALSE, error)) {
			g_string_free (phase2, TRUE);
			return FALSE;
		}
	}
	g_string_free (phase2, TRUE);

	/* PAC file */
	path = nm_setting_802_1x_get_pac_file (setting);
	if (path) {
		if (!add_string_val (self, path, "pac_file", FALSE, FALSE, error))
			return FALSE;
	} else {
		/* PAC file is not specified.
		 * If provisioning is allowed, use an blob format.
		 */
		if (fast_provisoning_allowed) {
			gs_free char *blob_name = NULL;

			blob_name = g_strdup_printf ("blob://pac-blob-%s", con_uuid);
			if (!add_string_val (self, blob_name, "pac_file", FALSE, FALSE, error))
				return FALSE;
		} else {
			/* This is only error for EAP-FAST; don't disturb other methods. */
			if (fast) {
				g_set_error (error, NM_SUPPLICANT_ERROR, NM_SUPPLICANT_ERROR_CONFIG,
				             "EAP-FAST error: no PAC file provided and "
				             "automatic PAC provisioning is disabled");
				return FALSE;
			}
		}
	}

	/* If user wants to use system CA certs, either populate ca_path (if the path
	 * is a directory) or ca_cert (the path is a file name) */
	if (nm_setting_802_1x_get_system_ca_certs (setting)) {
		if (g_file_test (SYSTEM_CA_PATH, G_FILE_TEST_IS_DIR))
			ca_path_override = SYSTEM_CA_PATH;
		else
			ca_cert_override = SYSTEM_CA_PATH;
	}

	/* CA path */
	path = nm_setting_802_1x_get_ca_path (setting);
	path = ca_path_override ? ca_path_override : path;
	if (path) {
		if (!add_string_val (self, path, "ca_path", FALSE, FALSE, error))
			return FALSE;
	}

	/* Phase2 CA path */
	path = nm_setting_802_1x_get_phase2_ca_path (setting);
	path = ca_path_override ? ca_path_override : path;
	if (path) {
		if (!add_string_val (self, path, "ca_path2", FALSE, FALSE, error))
			return FALSE;
	}

	/* CA certificate */
	if (ca_cert_override) {
		if (!add_string_val (self, ca_cert_override, "ca_cert", FALSE, FALSE, error))
			return FALSE;
	} else {
		switch (nm_setting_802_1x_get_ca_cert_scheme (setting)) {
		case NM_SETTING_802_1X_CK_SCHEME_BLOB:
			bytes = nm_setting_802_1x_get_ca_cert_blob (setting);
			if (!nm_supplicant_config_add_blob_for_connection (self, bytes, "ca_cert", con_uuid, error))
				return FALSE;
			break;
		case NM_SETTING_802_1X_CK_SCHEME_PATH:
			path = nm_setting_802_1x_get_ca_cert_path (setting);
			if (!add_string_val (self, path, "ca_cert", FALSE, FALSE, error))
				return FALSE;
			break;
		default:
			break;
		}
	}

	/* Phase 2 CA certificate */
	if (ca_cert_override) {
		if (!add_string_val (self, ca_cert_override, "ca_cert2", FALSE, FALSE, error))
			return FALSE;
	} else {
		switch (nm_setting_802_1x_get_phase2_ca_cert_scheme (setting)) {
		case NM_SETTING_802_1X_CK_SCHEME_BLOB:
			bytes = nm_setting_802_1x_get_phase2_ca_cert_blob (setting);
			if (!nm_supplicant_config_add_blob_for_connection (self, bytes, "ca_cert2", con_uuid, error))
				return FALSE;
			break;
		case NM_SETTING_802_1X_CK_SCHEME_PATH:
			path = nm_setting_802_1x_get_phase2_ca_cert_path (setting);
			if (!add_string_val (self, path, "ca_cert2", FALSE, FALSE, error))
				return FALSE;
			break;
		default:
			break;
		}
	}

	/* Subject match */
	value = nm_setting_802_1x_get_subject_match (setting);
	if (!add_string_val (self, value, "subject_match", FALSE, FALSE, error))
		return FALSE;
	value = nm_setting_802_1x_get_phase2_subject_match (setting);
	if (!add_string_val (self, value, "subject_match2", FALSE, FALSE, error))
		return FALSE;

	/* altSubjectName match */
	if (!ADD_STRING_LIST_VAL (self, setting, 802_1x, altsubject_match, altsubject_matches, "altsubject_match", ';', FALSE, FALSE, error))
		return FALSE;
	if (!ADD_STRING_LIST_VAL (self, setting, 802_1x, phase2_altsubject_match, phase2_altsubject_matches, "altsubject_match2", ';', FALSE, FALSE, error))
		return FALSE;

	/* Domain suffix match */
	value = nm_setting_802_1x_get_domain_suffix_match (setting);
	if (!add_string_val (self, value, "domain_suffix_match", FALSE, FALSE, error))
		return FALSE;
	value = nm_setting_802_1x_get_phase2_domain_suffix_match (setting);
	if (!add_string_val (self, value, "domain_suffix_match2", FALSE, FALSE, error))
		return FALSE;

	/* Private key */
	added = FALSE;
	switch (nm_setting_802_1x_get_private_key_scheme (setting)) {
	case NM_SETTING_802_1X_CK_SCHEME_BLOB:
		bytes = nm_setting_802_1x_get_private_key_blob (setting);
		if (!nm_supplicant_config_add_blob_for_connection (self, bytes, "private_key", con_uuid, error))
			return FALSE;
		added = TRUE;
		break;
	case NM_SETTING_802_1X_CK_SCHEME_PATH:
		path = nm_setting_802_1x_get_private_key_path (setting);
		if (!add_string_val (self, path, "private_key", FALSE, FALSE, error))
			return FALSE;
		added = TRUE;
		break;
	default:
		break;
	}

	if (added) {
		NMSetting8021xCKFormat format;
		NMSetting8021xCKScheme scheme;

		format = nm_setting_802_1x_get_private_key_format (setting);
		scheme = nm_setting_802_1x_get_private_key_scheme (setting);

		if (   scheme == NM_SETTING_802_1X_CK_SCHEME_PATH
		    || format == NM_SETTING_802_1X_CK_FORMAT_PKCS12) {
			/* Only add the private key password for PKCS#12 blobs and
			 * all path schemes, since in both of these cases the private key
			 * isn't decrypted at all.
			 */
			value = nm_setting_802_1x_get_private_key_password (setting);
			if (!add_string_val (self, value, "private_key_passwd", FALSE, TRUE, error))
				return FALSE;
		}

		if (format != NM_SETTING_802_1X_CK_FORMAT_PKCS12) {
			/* Only add the client cert if the private key is not PKCS#12, as
			 * wpa_supplicant configuration directs us to do.
			 */
			switch (nm_setting_802_1x_get_client_cert_scheme (setting)) {
			case NM_SETTING_802_1X_CK_SCHEME_BLOB:
				bytes = nm_setting_802_1x_get_client_cert_blob (setting);
				if (!nm_supplicant_config_add_blob_for_connection (self, bytes, "client_cert", con_uuid, error))
					return FALSE;
				break;
			case NM_SETTING_802_1X_CK_SCHEME_PATH:
				path = nm_setting_802_1x_get_client_cert_path (setting);
				if (!add_string_val (self, path, "client_cert", FALSE, FALSE, error))
					return FALSE;
				break;
			default:
				break;
			}
		}
	}

	/* Phase 2 private key */
	added = FALSE;
	switch (nm_setting_802_1x_get_phase2_private_key_scheme (setting)) {
	case NM_SETTING_802_1X_CK_SCHEME_BLOB:
		bytes = nm_setting_802_1x_get_phase2_private_key_blob (setting);
		if (!nm_supplicant_config_add_blob_for_connection (self, bytes, "private_key2", con_uuid, error))
			return FALSE;
		added = TRUE;
		break;
	case NM_SETTING_802_1X_CK_SCHEME_PATH:
		path = nm_setting_802_1x_get_phase2_private_key_path (setting);
		if (!add_string_val (self, path, "private_key2", FALSE, FALSE, error))
			return FALSE;
		added = TRUE;
		break;
	default:
		break;
	}

	if (added) {
		NMSetting8021xCKFormat format;
		NMSetting8021xCKScheme scheme;

		format = nm_setting_802_1x_get_phase2_private_key_format (setting);
		scheme = nm_setting_802_1x_get_phase2_private_key_scheme (setting);

		if (   scheme == NM_SETTING_802_1X_CK_SCHEME_PATH
		    || format == NM_SETTING_802_1X_CK_FORMAT_PKCS12) {
			/* Only add the private key password for PKCS#12 blobs and
			 * all path schemes, since in both of these cases the private key
			 * isn't decrypted at all.
			 */
			value = nm_setting_802_1x_get_phase2_private_key_password (setting);
			if (!add_string_val (self, value, "private_key2_passwd", FALSE, TRUE, error))
				return FALSE;
		}

		if (format != NM_SETTING_802_1X_CK_FORMAT_PKCS12) {
			/* Only add the client cert if the private key is not PKCS#12, as
			 * wpa_supplicant configuration directs us to do.
			 */
			switch (nm_setting_802_1x_get_phase2_client_cert_scheme (setting)) {
			case NM_SETTING_802_1X_CK_SCHEME_BLOB:
				bytes = nm_setting_802_1x_get_phase2_client_cert_blob (setting);
				if (!nm_supplicant_config_add_blob_for_connection (self, bytes, "client_cert2", con_uuid, error))
					return FALSE;
				break;
			case NM_SETTING_802_1X_CK_SCHEME_PATH:
				path = nm_setting_802_1x_get_phase2_client_cert_path (setting);
				if (!add_string_val (self, path, "client_cert2", FALSE, FALSE, error))
					return FALSE;
				break;
			default:
				break;
			}
		}
	}

	value = nm_setting_802_1x_get_identity (setting);
	if (!add_string_val (self, value, "identity", FALSE, FALSE, error))
		return FALSE;
	value = nm_setting_802_1x_get_anonymous_identity (setting);
	if (!add_string_val (self, value, "anonymous_identity", FALSE, FALSE, error))
		return FALSE;

	return TRUE;
}
예제 #22
0
static gboolean
fu_provider_chug_update (FuProvider *provider,
			 FuDevice *device,
			 GBytes *blob_fw,
			 FwupdInstallFlags flags,
			 GError **error)
{
	FuProviderChug *provider_chug = FU_PROVIDER_CHUG (provider);
	FuProviderChugPrivate *priv = GET_PRIVATE (provider_chug);
	FuProviderChugItem *item;
	g_autoptr(GError) error_local = NULL;

	/* find item */
	item = g_hash_table_lookup (priv->devices,
				    fu_device_get_id (device));
	if (item == NULL) {
		g_set_error (error,
			     FWUPD_ERROR,
			     FWUPD_ERROR_NOT_FOUND,
			     "cannot find: %s",
			     fu_device_get_id (device));
		return FALSE;
	}

	/* this file is so small, just slurp it all in one go */
	item->fw_bin = g_bytes_ref (blob_fw);

	/* check this firmware is actually for this device */
	if (!ch_device_check_firmware (item->usb_device,
				       g_bytes_get_data (item->fw_bin, NULL),
				       g_bytes_get_size (item->fw_bin),
				       &error_local)) {
		g_set_error (error,
			     FWUPD_ERROR,
			     FWUPD_ERROR_NOT_SUPPORTED,
			     "firmware is not suitable: %s",
			     error_local->message);
		return FALSE;
	}

	/* switch to bootloader mode */
	if (!item->is_bootloader) {
		g_debug ("ColorHug: Switching to bootloader mode");
		if (!fu_provider_chug_open (item, error))
			return FALSE;
		ch_device_queue_reset (priv->device_queue, item->usb_device);
		fu_provider_set_status (provider, FWUPD_STATUS_DEVICE_RESTART);
		if (!ch_device_queue_process (priv->device_queue,
					      CH_DEVICE_QUEUE_PROCESS_FLAGS_NONE,
					      NULL, &error_local)) {
			g_set_error (error,
				     FWUPD_ERROR,
				     FWUPD_ERROR_WRITE,
				     "failed to reset device: %s",
				     error_local->message);
			g_usb_device_close (item->usb_device, NULL);
			return FALSE;
		}

		/* this device has just gone away, no error possible */
		g_usb_device_close (item->usb_device, NULL);

		/* wait for reconnection */
		g_debug ("ColorHug: Waiting for bootloader");
		if (!fu_provider_chug_wait_for_connect (provider_chug, item, error))
			return FALSE;
	}

	/* open the device, which is now in bootloader mode */
	if (!fu_provider_chug_open (item, error))
		return FALSE;

	/* write firmware */
	g_debug ("ColorHug: Writing firmware");
	ch_device_queue_write_firmware (priv->device_queue, item->usb_device,
					g_bytes_get_data (item->fw_bin, NULL),
					g_bytes_get_size (item->fw_bin));
	fu_provider_set_status (provider, FWUPD_STATUS_DEVICE_WRITE);
	if (!ch_device_queue_process (priv->device_queue,
				      CH_DEVICE_QUEUE_PROCESS_FLAGS_NONE,
				      NULL, &error_local)) {
		g_set_error (error,
			     FWUPD_ERROR,
			     FWUPD_ERROR_WRITE,
			     "failed to write firmware: %s",
			     error_local->message);
		g_usb_device_close (item->usb_device, NULL);
		return FALSE;
	}

	/* verify firmware */
	g_debug ("ColorHug: Veifying firmware");
	ch_device_queue_verify_firmware (priv->device_queue, item->usb_device,
					 g_bytes_get_data (item->fw_bin, NULL),
					 g_bytes_get_size (item->fw_bin));
	fu_provider_set_status (provider, FWUPD_STATUS_DEVICE_VERIFY);
	if (!ch_device_queue_process (priv->device_queue,
				      CH_DEVICE_QUEUE_PROCESS_FLAGS_NONE,
				      NULL, &error_local)) {
		g_set_error (error,
			     FWUPD_ERROR,
			     FWUPD_ERROR_WRITE,
			     "failed to verify firmware: %s",
			     error_local->message);
		g_usb_device_close (item->usb_device, NULL);
		return FALSE;
	}

	/* boot into the new firmware */
	g_debug ("ColorHug: Booting new firmware");
	ch_device_queue_boot_flash (priv->device_queue, item->usb_device);
	fu_provider_set_status (provider, FWUPD_STATUS_DEVICE_RESTART);
	if (!ch_device_queue_process (priv->device_queue,
				      CH_DEVICE_QUEUE_PROCESS_FLAGS_NONE,
				      NULL, &error_local)) {
		g_set_error (error,
			     FWUPD_ERROR,
			     FWUPD_ERROR_WRITE,
			     "failed to boot flash: %s",
			     error_local->message);
		g_usb_device_close (item->usb_device, NULL);
		return FALSE;
	}

	/* this device has just gone away, no error possible */
	g_usb_device_close (item->usb_device, NULL);

	/* wait for firmware mode */
	if (!fu_provider_chug_wait_for_connect (provider_chug, item, error))
		return FALSE;
	if (!fu_provider_chug_open (item, error))
		return FALSE;

	/* set flash success */
	g_debug ("ColorHug: Setting flash success");
	ch_device_queue_set_flash_success (priv->device_queue, item->usb_device, 1);
	if (!ch_device_queue_process (priv->device_queue,
				      CH_DEVICE_QUEUE_PROCESS_FLAGS_NONE,
				      NULL, &error_local)) {
		g_set_error (error,
			     FWUPD_ERROR,
			     FWUPD_ERROR_WRITE,
			     "failed to set flash success: %s",
			     error_local->message);
		g_usb_device_close (item->usb_device, NULL);
		return FALSE;
	}

	/* close, orderly */
	if (!g_usb_device_close (item->usb_device, &error_local)) {
		g_set_error (error,
			     FWUPD_ERROR,
			     FWUPD_ERROR_WRITE,
			     "failed to close device: %s",
			     error_local->message);
		g_usb_device_close (item->usb_device, NULL);
		return FALSE;
	}

	/* get the new firmware version */
	g_debug ("ColorHug: Getting new firmware version");
	item->got_version = FALSE;
	fu_provider_chug_get_firmware_version (item);

	if (item->got_version)
		g_debug ("ColorHug: DONE!");

	return TRUE;
}
예제 #23
0
static gboolean
builder_source_file_extract (BuilderSource *source,
                             GFile *dest,
                             BuilderContext *context,
                             GError **error)
{
  BuilderSourceFile *self = BUILDER_SOURCE_FILE (source);
  g_autoptr(GFile) src = NULL;
  g_autoptr(GFile) dest_file = NULL;
  g_autofree char *dest_filename = NULL;
  gboolean is_local, is_inline;

  src = get_source_file (self, context, &is_local, &is_inline, error);
  if (src == NULL)
    return FALSE;

  if (self->dest_filename)
    dest_filename = g_strdup (self->dest_filename);
  else
    {
      if (is_inline)
        {
          g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                       "No dest-filename set for inline file data");
          return FALSE;
        }
      dest_filename = g_file_get_basename (src);
    }

  dest_file = g_file_get_child (dest, dest_filename);

  if (is_inline)
    {
      g_autoptr(GBytes) content = NULL;

      content = download_uri (self->url,
                              context,
                              error);
      if (content == NULL)
        return FALSE;

      if (!g_file_replace_contents (dest_file,
                                    g_bytes_get_data (content, NULL),
                                    g_bytes_get_size (content),
                                    NULL, FALSE, G_FILE_CREATE_NONE, NULL,
                                    NULL, error))
        return FALSE;
    }
  else
    {
      if (is_local)
        {
          g_autofree char *data = NULL;
          g_autofree char *base64 = NULL;
          gsize len;

          if (!g_file_load_contents (src, NULL, &data, &len, NULL, error))
            return FALSE;

          base64 = g_base64_encode ((const guchar *)data, len);
          g_free (self->url);
          self->url = g_strdup_printf ("data:text/plain;charset=utf8;base64,%s", base64);
          if (self->dest_filename == NULL || *self->dest_filename == 0)
            {
              g_free (self->dest_filename);
              self->dest_filename = g_file_get_basename (src);
            }
        }

      if (!g_file_copy (src, dest_file,
                        G_FILE_COPY_OVERWRITE,
                        NULL,
                        NULL, NULL,
                        error))
        return FALSE;
    }

  return TRUE;
}
예제 #24
0
static void
add_data_tab (const gchar *demoname)
{
  gchar *resource_dir, *resource_name, *content_type, *content_mime;
  gchar **resources;
  GBytes *bytes;
  GtkWidget *widget, *label;
  guint i;

  resource_dir = g_strconcat ("/", demoname, NULL);
  resources = g_resources_enumerate_children (resource_dir, 0, NULL);
  if (resources == NULL)
    {
      g_free (resource_dir);
      return;
    }

  for (i = 0; resources[i]; i++)
    {
      resource_name = g_strconcat (resource_dir, "/", resources[i], NULL);
      bytes = g_resources_lookup_data (resource_name, 0, NULL);
      g_assert (bytes);

      content_type = g_content_type_guess (resource_name,
                                           g_bytes_get_data (bytes, NULL),
                                           g_bytes_get_size (bytes),
                                           NULL);
      content_mime = g_content_type_get_mime_type (content_type);

      /* In theory we should look at all the mime types gdk-pixbuf supports
       * and go from there, but we know what file types we've added.
       */
      if (g_content_type_is_a (content_mime, "image/png") ||
          g_content_type_is_a (content_mime, "image/gif") ||
          g_content_type_is_a (content_mime, "image/jpeg"))
        {
          widget = gtk_image_new_from_resource (resource_name);
        }
      else if (g_content_type_is_a (content_mime, "text/plain") ||
               g_content_type_is_a (content_mime, "application/x-ext-ui") ||
               g_content_type_is_a (content_mime, "text/css"))
        {
          GtkTextBuffer *buffer;
          GtkWidget *textview;

          widget = create_text (&textview, FALSE);
          buffer = gtk_text_buffer_new (NULL);
          gtk_text_buffer_set_text (buffer, g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes));
          gtk_text_view_set_buffer (GTK_TEXT_VIEW (textview), buffer);
        }
      else
        {

          g_warning ("Don't know how to display resource '%s' of type '%s'\n", resource_name, content_mime);
          widget = NULL;
        }

      gtk_widget_show_all (widget);
      label = gtk_label_new (resources[i]);
      gtk_widget_show (label);
      gtk_notebook_append_page (GTK_NOTEBOOK (notebook), widget, label);
      gtk_container_child_set (GTK_CONTAINER (notebook),
                               GTK_WIDGET (widget),
                               "tab-expand", TRUE,
                               NULL);

      g_free (content_mime);
      g_free (content_type);
      g_free (resource_name);
      g_bytes_unref (bytes);
    }

  g_strfreev (resources);
  g_free (resource_dir);
}
예제 #25
0
int
main (int argc, char *argv[])
{
    char *bad_domains = NULL;
    GError *error = NULL;
    gboolean wrote_pidfile = FALSE;
    gs_free char *pidfile = NULL;
    gs_unref_object NMDhcpClient *dhcp4_client = NULL;
    gs_unref_object NMRDisc *rdisc = NULL;
    GByteArray *hwaddr = NULL;
    size_t hwaddr_len = 0;
    gconstpointer tmp;
    gs_free NMUtilsIPv6IfaceId *iid = NULL;
    guint sd_id;

    nm_g_type_init ();

    setpgid (getpid (), getpid ());

    do_early_setup (&argc, &argv);

    if (global_opt.g_fatal_warnings) {
        GLogLevelFlags fatal_mask;

        fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK);
        fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL;
        g_log_set_always_fatal (fatal_mask);
    }

    if (global_opt.show_version) {
        fprintf (stdout, NM_DIST_VERSION "\n");
        exit (0);
    }

    nm_main_utils_ensure_root ();

    if (!global_opt.ifname || !global_opt.uuid) {
        fprintf (stderr, _("An interface name and UUID are required\n"));
        exit (1);
    }

    ifindex = if_nametoindex (global_opt.ifname);
    if (ifindex <= 0) {
        fprintf (stderr, _("Failed to find interface index for %s (%s)\n"), global_opt.ifname, strerror (errno));
        exit (1);
    }
    pidfile = g_strdup_printf (NMIH_PID_FILE_FMT, ifindex);
    nm_main_utils_ensure_not_running_pidfile (pidfile);

    nm_main_utils_ensure_rundir ();

    if (!nm_logging_setup (global_opt.opt_log_level,
                           global_opt.opt_log_domains,
                           &bad_domains,
                           &error)) {
        fprintf (stderr,
                 _("%s.  Please use --help to see a list of valid options.\n"),
                 error->message);
        exit (1);
    } else if (bad_domains) {
        fprintf (stderr,
                 _("Ignoring unrecognized log domain(s) '%s' passed on command line.\n"),
                 bad_domains);
        g_clear_pointer (&bad_domains, g_free);
    }

    if (global_opt.become_daemon && !global_opt.debug) {
        if (daemon (0, 0) < 0) {
            int saved_errno;

            saved_errno = errno;
            fprintf (stderr, _("Could not daemonize: %s [error %u]\n"),
                     g_strerror (saved_errno),
                     saved_errno);
            exit (1);
        }
        if (nm_main_utils_write_pidfile (pidfile))
            wrote_pidfile = TRUE;
    }

    /* Set up unix signal handling - before creating threads, but after daemonizing! */
    main_loop = g_main_loop_new (NULL, FALSE);
    setup_signals ();

    nm_logging_syslog_openlog (global_opt.logging_backend
                               ? global_opt.logging_backend
                               : (global_opt.debug ? "debug" : NULL));

    nm_log_info (LOGD_CORE, "nm-iface-helper (version " NM_DIST_VERSION ") is starting...");

    /* Set up platform interaction layer */
    nm_linux_platform_setup ();

    tmp = nm_platform_link_get_address (NM_PLATFORM_GET, ifindex, &hwaddr_len);
    if (tmp) {
        hwaddr = g_byte_array_sized_new (hwaddr_len);
        g_byte_array_append (hwaddr, tmp, hwaddr_len);
    }

    if (global_opt.iid_str) {
        GBytes *bytes;
        gsize ignored = 0;

        bytes = nm_utils_hexstr2bin (global_opt.iid_str);
        if (!bytes || g_bytes_get_size (bytes) != sizeof (*iid)) {
            fprintf (stderr, _("(%s): Invalid IID %s\n"), global_opt.ifname, global_opt.iid_str);
            exit (1);
        }
        iid = g_bytes_unref_to_data (bytes, &ignored);
    }

    if (global_opt.dhcp4_address) {
        nm_platform_sysctl_set (NM_PLATFORM_GET, nm_utils_ip4_property_path (global_opt.ifname, "promote_secondaries"), "1");

        dhcp4_client = nm_dhcp_manager_start_ip4 (nm_dhcp_manager_get (),
                       global_opt.ifname,
                       ifindex,
                       hwaddr,
                       global_opt.uuid,
                       global_opt.priority_v4,
                       !!global_opt.dhcp4_hostname,
                       global_opt.dhcp4_hostname,
                       global_opt.dhcp4_fqdn,
                       global_opt.dhcp4_clientid,
                       45,
                       NULL,
                       global_opt.dhcp4_address);
        g_assert (dhcp4_client);
        g_signal_connect (dhcp4_client,
                          NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED,
                          G_CALLBACK (dhcp4_state_changed),
                          NULL);
    }

    if (global_opt.slaac) {
        nm_platform_link_set_user_ipv6ll_enabled (NM_PLATFORM_GET, ifindex, TRUE);

        rdisc = nm_lndp_rdisc_new (NM_PLATFORM_GET, ifindex, global_opt.ifname, global_opt.uuid, global_opt.addr_gen_mode, NULL);
        g_assert (rdisc);

        if (iid)
            nm_rdisc_set_iid (rdisc, *iid);

        nm_platform_sysctl_set (NM_PLATFORM_GET, nm_utils_ip6_property_path (global_opt.ifname, "accept_ra"), "1");
        nm_platform_sysctl_set (NM_PLATFORM_GET, nm_utils_ip6_property_path (global_opt.ifname, "accept_ra_defrtr"), "0");
        nm_platform_sysctl_set (NM_PLATFORM_GET, nm_utils_ip6_property_path (global_opt.ifname, "accept_ra_pinfo"), "0");
        nm_platform_sysctl_set (NM_PLATFORM_GET, nm_utils_ip6_property_path (global_opt.ifname, "accept_ra_rtr_pref"), "0");

        g_signal_connect (NM_PLATFORM_GET,
                          NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED,
                          G_CALLBACK (ip6_address_changed),
                          rdisc);
        g_signal_connect (rdisc,
                          NM_RDISC_CONFIG_CHANGED,
                          G_CALLBACK (rdisc_config_changed),
                          NULL);
        g_signal_connect (rdisc,
                          NM_RDISC_RA_TIMEOUT,
                          G_CALLBACK (rdisc_ra_timeout),
                          NULL);
        nm_rdisc_start (rdisc);
    }

    sd_id = nm_sd_event_attach_default ();

    g_main_loop_run (main_loop);

    g_clear_pointer (&hwaddr, g_byte_array_unref);

    if (pidfile && wrote_pidfile)
        unlink (pidfile);

    nm_log_info (LOGD_CORE, "exiting");

    nm_clear_g_source (&sd_id);
    exit (0);
}
static void
request_secrets_from_ui (NMSecretAgentSimpleRequest *request)
{
	GPtrArray *secrets;
	NMSecretAgentSimpleSecret *secret;
	const char *title;
	char *msg;
	gboolean ok = TRUE;

	secrets = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_secret_agent_simple_secret_free);

	if (nm_connection_is_type (request->connection, NM_SETTING_WIRELESS_SETTING_NAME)) {
		NMSettingWireless *s_wireless;
		GBytes *ssid;
		char *ssid_utf8;

		s_wireless = nm_connection_get_setting_wireless (request->connection);
		ssid = nm_setting_wireless_get_ssid (s_wireless);
		ssid_utf8 = nm_utils_ssid_to_utf8 (g_bytes_get_data (ssid, NULL),
		                                   g_bytes_get_size (ssid));

		title = _("Authentication required by wireless network");
		msg = g_strdup_printf (_("Passwords or encryption keys are required to access the wireless network '%s'."), ssid_utf8);

		ok = add_wireless_secrets (request, secrets);
	} else if (nm_connection_is_type (request->connection, NM_SETTING_WIRED_SETTING_NAME)) {
		NMSettingConnection *s_con;

		s_con = nm_connection_get_setting_connection (request->connection);

		title = _("Wired 802.1X authentication");
		msg = NULL;

		secret = nm_secret_agent_simple_secret_new (_("Network name"),
		                                            NM_SETTING (s_con),
		                                            NM_SETTING_CONNECTION_ID,
		                                            FALSE);
		g_ptr_array_add (secrets, secret);
		ok = add_8021x_secrets (request, secrets);
	} else if (nm_connection_is_type (request->connection, NM_SETTING_PPPOE_SETTING_NAME)) {
		title = _("DSL authentication");
		msg = NULL;

		ok = add_pppoe_secrets (request, secrets);
	} else if (nm_connection_is_type (request->connection, NM_SETTING_GSM_SETTING_NAME)) {
		NMSettingGsm *s_gsm = nm_connection_get_setting_gsm (request->connection);

		if (strv_has (request->hints, "pin")) {
			title = _("PIN code required");
			msg = g_strdup (_("PIN code is needed for the mobile broadband device"));

			secret = nm_secret_agent_simple_secret_new (_("PIN"),
			                                            NM_SETTING (s_gsm),
			                                            NM_SETTING_GSM_PIN,
			                                            FALSE);
			g_ptr_array_add (secrets, secret);
		} else {
			title = _("Mobile broadband network password");
			msg = g_strdup_printf (_("A password is required to connect to '%s'."),
			                       nm_connection_get_id (request->connection));

			secret = nm_secret_agent_simple_secret_new (_("Password"),
			                                            NM_SETTING (s_gsm),
			                                            NM_SETTING_GSM_PASSWORD,
			                                            TRUE);
			g_ptr_array_add (secrets, secret);
		}
	} else if (nm_connection_is_type (request->connection, NM_SETTING_CDMA_SETTING_NAME)) {
		NMSettingCdma *s_cdma = nm_connection_get_setting_cdma (request->connection);

		title = _("Mobile broadband network password");
		msg = g_strdup_printf (_("A password is required to connect to '%s'."),
		                       nm_connection_get_id (request->connection));

		secret = nm_secret_agent_simple_secret_new (_("Password"),
		                                            NM_SETTING (s_cdma),
		                                            NM_SETTING_CDMA_PASSWORD,
		                                            TRUE);
		g_ptr_array_add (secrets, secret);
	} else if (nm_connection_is_type (request->connection, NM_SETTING_BLUETOOTH_SETTING_NAME)) {
		NMSetting *setting;

		setting = nm_connection_get_setting_by_name (request->connection, NM_SETTING_GSM_SETTING_NAME);
		if (!setting)
			setting = nm_connection_get_setting_by_name (request->connection, NM_SETTING_CDMA_SETTING_NAME);

		title = _("Mobile broadband network password");
		msg = g_strdup_printf (_("A password is required to connect to '%s'."),
		                       nm_connection_get_id (request->connection));

		secret = nm_secret_agent_simple_secret_new (_("Password"),
		                                            setting,
		                                            "password",
		                                            TRUE);
		g_ptr_array_add (secrets, secret);
	} else
		ok = FALSE;

	if (!ok) {
		g_ptr_array_unref (secrets);
		return;
	}

	g_signal_emit (request->self, signals[REQUEST_SECRETS], 0,
	               request->request_id, title, msg, secrets);
}
예제 #27
0
파일: dfu-patch.c 프로젝트: vathpela/fwupd
/**
 * dfu_patch_export:
 * @self: a #DfuPatch
 * @error: a #GError, or %NULL
 *
 * Converts the patch to a binary blob that can be stored as a file.
 *
 * Return value: (transfer full): blob
 **/
GBytes *
dfu_patch_export (DfuPatch *self, GError **error)
{
	DfuPatchPrivate *priv = GET_PRIVATE (self);
	gsize addr;
	gsize sz;
	guint8 *data;

	g_return_val_if_fail (DFU_IS_PATCH (self), NULL);

	/* check we have something to write */
	if (priv->chunks->len == 0) {
		g_set_error_literal (error,
				     FWUPD_ERROR,
				     FWUPD_ERROR_INVALID_FILE,
				     "no chunks to process");
		return NULL;
	}

	/* calculate the size of the new blob */
	sz = sizeof(DfuPatchFileHeader);
	for (guint i = 0; i < priv->chunks->len; i++) {
		DfuPatchChunk *chunk = g_ptr_array_index (priv->chunks, i);
		sz += sizeof(DfuPatchChunkHeader) + g_bytes_get_size (chunk->blob);
	}
	g_debug ("blob size is %" G_GSIZE_FORMAT, sz);

	/* actually allocate and fill in the blob */
	data = g_malloc0 (sz);
	memcpy (data, "DfuP", 4);

	/* add checksums */
	if (priv->checksum_old != NULL) {
		gsize csum_sz = 0;
		const guint8 *csum_data = g_bytes_get_data (priv->checksum_old, &csum_sz);
		memcpy (data + G_STRUCT_OFFSET(DfuPatchFileHeader,checksum_old),
			csum_data, csum_sz);
	}
	if (priv->checksum_new != NULL) {
		gsize csum_sz = 0;
		const guint8 *csum_data = g_bytes_get_data (priv->checksum_new, &csum_sz);
		memcpy (data + G_STRUCT_OFFSET(DfuPatchFileHeader,checksum_new),
			csum_data, csum_sz);
	}

	addr = sizeof(DfuPatchFileHeader);
	for (guint i = 0; i < priv->chunks->len; i++) {
		DfuPatchChunk *chunk = g_ptr_array_index (priv->chunks, i);
		DfuPatchChunkHeader chunkhdr;
		gsize sz_tmp = 0;
		const guint8 *data_new = g_bytes_get_data (chunk->blob, &sz_tmp);

		/* build chunk header and append data */
		chunkhdr.off = GUINT32_TO_LE (chunk->off);
		chunkhdr.sz = GUINT32_TO_LE (sz_tmp);
		chunkhdr.flags = 0;
		memcpy (data + addr, &chunkhdr, sizeof(DfuPatchChunkHeader));
		memcpy (data + addr + sizeof(DfuPatchChunkHeader), data_new, sz_tmp);

		/* move up after the copied data */
		addr += sizeof(DfuPatchChunkHeader) + sz_tmp;
	}
	return g_bytes_new_take (data, sz);

}
예제 #28
0
static gboolean
gs_plugin_fwupd_refresh_remote (GsPlugin *plugin,
				FwupdRemote *remote,
				guint cache_age,
				GCancellable *cancellable,
				GError **error)
{
	GsPluginData *priv = gs_plugin_get_data (plugin);
	GChecksumType checksum_kind;
	const gchar *url_sig = NULL;
	const gchar *url = NULL;
	g_autoptr(GError) error_local = NULL;
	g_autofree gchar *basename = NULL;
	g_autofree gchar *basename_sig = NULL;
	g_autofree gchar *cache_id = NULL;
	g_autofree gchar *checksum = NULL;
	g_autofree gchar *filename = NULL;
	g_autofree gchar *filename_sig = NULL;
	g_autoptr(GBytes) data = NULL;
	g_autoptr(GsApp) app_dl = gs_app_new (gs_plugin_get_name (plugin));

	/* sanity check */
	if (fwupd_remote_get_filename_cache_sig (remote) == NULL) {
		g_set_error (error,
			     GS_PLUGIN_ERROR,
			     GS_PLUGIN_ERROR_FAILED,
			     "remote %s has no cache signature",
			     fwupd_remote_get_id (remote));
		return FALSE;
	}

	/* check cache age */
	if (cache_age > 0) {
		guint64 age = fwupd_remote_get_age (remote);
		guint tmp = age < G_MAXUINT ? (guint) age : G_MAXUINT;
		if (tmp < cache_age) {
			g_debug ("%s is only %u seconds old, so ignoring refresh",
				 filename_sig, tmp);
			return TRUE;
		}
	}

	/* download the signature first, it's smaller */
	cache_id = g_strdup_printf ("fwupd/remotes.d/%s", fwupd_remote_get_id (remote));
	basename_sig = g_path_get_basename (fwupd_remote_get_filename_cache_sig (remote));
	filename_sig = gs_utils_get_cache_filename (cache_id, basename_sig,
						    GS_UTILS_CACHE_FLAG_WRITEABLE,
						    error);

	/* download the signature first, it's smaller */
	url_sig = fwupd_remote_get_metadata_uri_sig (remote);
	gs_app_set_summary_missing (app_dl,
				    /* TRANSLATORS: status text when downloading */
				    _("Downloading firmware update signature…"));
	data = gs_plugin_download_data (plugin, app_dl, url_sig, cancellable, error);
	if (data == NULL) {
		gs_utils_error_add_origin_id (error, priv->cached_origin);
		return FALSE;
	}

	/* is the signature hash the same as we had before? */
	checksum_kind = fwupd_checksum_guess_kind (fwupd_remote_get_checksum (remote));
	checksum = g_compute_checksum_for_data (checksum_kind,
						(const guchar *) g_bytes_get_data (data, NULL),
						g_bytes_get_size (data));
	if (g_strcmp0 (checksum, fwupd_remote_get_checksum (remote)) == 0) {
		g_debug ("signature of %s is unchanged", url_sig);
		return TRUE;
	}

	/* save to a file */
	g_debug ("saving new remote signature to %s:", filename_sig);
	if (!g_file_set_contents (filename_sig,
				  g_bytes_get_data (data, NULL),
				  (guint) g_bytes_get_size (data),
				  &error_local)) {
		g_set_error (error,
			     GS_PLUGIN_ERROR,
			     GS_PLUGIN_ERROR_WRITE_FAILED,
			     "Failed to save firmware signature: %s",
			     error_local->message);
		return FALSE;
	}

	/* download the payload and save to file */
	basename = g_path_get_basename (fwupd_remote_get_filename_cache (remote));
	filename = gs_utils_get_cache_filename (cache_id, basename,
						GS_UTILS_CACHE_FLAG_WRITEABLE,
						error);
	if (filename == NULL)
		return FALSE;
	g_debug ("saving new firmware metadata to %s:", filename);
	gs_app_set_summary_missing (app_dl,
				    /* TRANSLATORS: status text when downloading */
				    _("Downloading firmware update metadata…"));
	url = fwupd_remote_get_metadata_uri (remote);
	if (!gs_plugin_download_file (plugin, app_dl, url, filename,
				      cancellable, error)) {
		gs_utils_error_add_origin_id (error, priv->cached_origin);
		return FALSE;
	}

	/* phew, lets send all this to fwupd */
	if (!fwupd_client_update_metadata (priv->client,
					   fwupd_remote_get_id (remote),
					   filename,
					   filename_sig,
					   cancellable,
					   error)) {
		gs_plugin_fwupd_error_convert (error);
		return FALSE;
	}
	return TRUE;
}
static gboolean
gkm_gnome2_private_key_real_load (GkmSerializable *base,
                                  GkmSecret *login,
                                  GBytes *data)
{
	GkmGnome2PrivateKey *self = GKM_GNOME2_PRIVATE_KEY (base);
	GkmDataResult res;
	gcry_sexp_t sexp, pub;
	GkmSexp *wrapper;
	const gchar *password;
	gsize n_password;

	if (g_bytes_get_size (data) == 0)
		return FALSE;

	res = gkm_data_der_read_private_pkcs8 (data, NULL, 0, &sexp);

	/* An unencrypted pkcs8 file */
	if (res == GKM_DATA_SUCCESS) {
		self->is_encrypted = FALSE;

	/* If it's locked, then use our token password */
	} else if (res == GKM_DATA_LOCKED) {
		self->is_encrypted = TRUE;

		if (!login) {
			g_message ("encountered private key but no private key present");
			return FALSE;
		}

		password = gkm_secret_get_password (login, &n_password);
		res = gkm_data_der_read_private_pkcs8 (data, password, n_password, &sexp);
	}

	switch (res) {
	case GKM_DATA_LOCKED:
		g_message ("private key is encrypted with wrong password");
		return FALSE;
	case GKM_DATA_FAILURE:
		g_message ("couldn't parse private key");
		return FALSE;
	case GKM_DATA_UNRECOGNIZED:
		g_message ("invalid or unrecognized private key");
		return FALSE;
	case GKM_DATA_SUCCESS:
		break;
	default:
		g_assert_not_reached();
	}

	/* Calculate a public key as our 'base' */
	if (!gkm_sexp_key_to_public (sexp, &pub))
		g_return_val_if_reached (FALSE);

	/* Keep the public part of the key around for answering queries */
	wrapper = gkm_sexp_new (pub);
	gkm_sexp_key_set_base (GKM_SEXP_KEY (self), wrapper);
	gkm_sexp_unref (wrapper);

	/* Encrypted private key, keep login and data */
	if (self->is_encrypted) {
		if (self->private_bytes)
			g_bytes_unref (self->private_bytes);
		self->private_bytes = g_bytes_ref (data);

		g_object_ref (login);
		if (self->login)
			g_object_unref (self->login);
		self->login = login;

		/* Don't need the private key any more */
		gcry_sexp_release (sexp);

	/* Not encrypted, just keep the parsed key */
	} else {
		wrapper = gkm_sexp_new (sexp);
		if (self->private_sexp)
			gkm_sexp_unref (self->private_sexp);
		self->private_sexp = wrapper;

		if (self->login)
			g_object_unref (login);
		self->login = NULL;
	}

	return TRUE;
}
예제 #30
0
static gboolean
package_checksum_file (GChecksum *checksum,
                       GHashTable *depends,
                       const gchar *root,
                       const gchar *filename)
{
  gchar *path = NULL;
  const gchar *string;
  GError *error = NULL;
  GChecksum *inner = NULL;
  GMappedFile *mapped = NULL;
  gboolean ret = FALSE;
  GList *output = NULL;
  GBytes *bytes;
  GList *l;

  if (!validate_path (filename))
    {
      g_warning ("package has an invalid path name: %s", filename);
      goto out;
    }

  path = g_build_filename (root, filename, NULL);
  if (g_file_test (path, G_FILE_TEST_IS_DIR))
    {
      ret = package_checksum_directory (checksum, depends, root, filename);
      goto out;
    }

  mapped = g_mapped_file_new (path, FALSE, &error);
  if (error)
    {
      g_warning ("couldn't open file: %s: %s", path, error->message);
      g_error_free (error);
      goto out;
    }

  bytes = g_mapped_file_get_bytes (mapped);
  output = cockpit_template_expand (bytes, gather_depends, depends);
  g_bytes_unref (bytes);

  inner = g_checksum_new (G_CHECKSUM_SHA1);

  for (l = output; l != NULL; l = g_list_next (l))
    {
      g_checksum_update (inner,
                         g_bytes_get_data (l->data, NULL),
                         g_bytes_get_size (l->data));
    }

  string = g_checksum_get_string (inner);

  /*
   * Place file name and hex checksum into checksum,
   * include the null terminators so these values
   * cannot be accidentally have a boundary discrepancy.
   */
  g_checksum_update (checksum, (const guchar *)filename,
                     strlen (filename) + 1);
  g_checksum_update (checksum, (const guchar *)string,
                     strlen (string) + 1);
  ret = TRUE;

out:
  g_list_free_full (output, (GDestroyNotify)g_bytes_unref);
  g_checksum_free (inner);
  if (mapped)
    g_mapped_file_unref (mapped);
  g_free (path);
  return ret;
}