void
empathy_tls_verifier_store_exception (EmpathyTLSVerifier *self)
{
  GArray *data;
  GcrCertificate *cert;
  GPtrArray *cert_data = NULL;
  GError *error = NULL;
  EmpathyTLSVerifierPriv *priv = GET_PRIV (self);

  g_object_get (priv->certificate, "cert-data", &cert_data, NULL);
  g_return_if_fail (cert_data);

  if (!cert_data->len)
    {
      DEBUG ("No certificate to pin.");
      return;
    }

  /* The first certificate in the chain is for the host */
  data = g_ptr_array_index (cert_data, 0);
  cert = gcr_simple_certificate_new ((gpointer)data->data, data->len);

  DEBUG ("Storing pinned certificate:");
  debug_certificate (cert);

  if (!gcr_trust_add_pinned_certificate (cert, GCR_PURPOSE_CLIENT_AUTH,
          priv->hostname, NULL, &error))
      DEBUG ("Can't store the pinned certificate: %s", error->message);

  g_object_unref (cert);
  g_boxed_free (TP_ARRAY_TYPE_UCHAR_ARRAY_LIST, cert_data);
}
static GtkWidget *
build_gcr_widget (EmpathyTLSDialog *self)
{
  GcrCertificateWidget *widget;
  GcrCertificate *certificate;
  GPtrArray *cert_chain = NULL;
  GArray *first_cert;
  int height;
  EmpathyTLSDialogPriv *priv = GET_PRIV (self);

  g_object_get (priv->certificate,
      "cert-data", &cert_chain,
      NULL);
  first_cert = g_ptr_array_index (cert_chain, 0);

  certificate = gcr_simple_certificate_new ((const guchar *) first_cert->data,
      first_cert->len);
  widget = gcr_certificate_widget_new (certificate);

  /* FIXME: make this widget bigger by default -- GTK+ should really handle
   * this sort of thing for us */
  gtk_widget_get_preferred_height (GTK_WIDGET (widget), NULL, &height);
  /* force the widget to at least 150 pixels high */
  gtk_widget_set_size_request (GTK_WIDGET (widget), -1, MAX (height, 150));

  g_object_unref (certificate);
  g_ptr_array_unref (cert_chain);

  return GTK_WIDGET (widget);
}
static void
test_details (const gchar *path)
{
	GcrCertificateDetailsWidget *details;
	GcrCertificate *certificate;
	GtkDialog *dialog;
	guchar *data;
	gsize n_data;
	
	if (!g_file_get_contents (path, (gchar**)&data, &n_data, NULL))
		g_error ("couldn't read file: %s", path);
	
	certificate = gcr_simple_certificate_new (data, n_data);
	g_assert (certificate);
	g_free (data);
	
	dialog = GTK_DIALOG (gtk_dialog_new ());
	g_object_ref_sink (dialog);
	
	details = gcr_certificate_details_widget_new (certificate);
	gtk_widget_show (GTK_WIDGET (details));
	gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (dialog)), GTK_WIDGET (details));

	gtk_window_set_default_size (GTK_WINDOW (dialog), 400, 400);
	gtk_dialog_run (dialog);
	
	g_object_unref (dialog);
	g_object_unref (certificate);
	g_object_unref (details);
}
void
empathy_tls_verifier_verify_async (EmpathyTLSVerifier *self,
    GAsyncReadyCallback callback,
    gpointer user_data)
{
  GcrCertificateChain *chain;
  GcrCertificate *cert;
  GPtrArray *cert_data = NULL;
  GArray *data;
  guint idx;
  EmpathyTLSVerifierPriv *priv = GET_PRIV (self);

  DEBUG ("Starting verification");

  g_return_if_fail (priv->verify_result == NULL);

  g_object_get (priv->certificate, "cert-data", &cert_data, NULL);
  g_return_if_fail (cert_data);

  priv->verify_result = g_simple_async_result_new (G_OBJECT (self),
      callback, user_data, NULL);

  /* Create a certificate chain */
  chain = gcr_certificate_chain_new ();
  for (idx = 0; idx < cert_data->len; ++idx) {
    data = g_ptr_array_index (cert_data, idx);
    cert = gcr_simple_certificate_new ((guchar *) data->data, data->len);
    gcr_certificate_chain_add (chain, cert);
    g_object_unref (cert);
  }

  gcr_certificate_chain_build_async (chain, GCR_PURPOSE_CLIENT_AUTH, priv->hostname, 0,
          NULL, perform_verification_cb, g_object_ref (self));

  g_object_unref (chain);
  g_boxed_free (TP_ARRAY_TYPE_UCHAR_ARRAY_LIST, cert_data);
}
Beispiel #5
0
static ETrustPromptResponse
trust_prompt_show (GtkWindow *parent,
		   const gchar *source_extension,
		   const gchar *source_display_name,
		   const gchar *host,
		   const gchar *error_text,
		   GcrParsed *parsed,
		   const gchar *reason,
		   void (* dialog_ready_cb) (GtkDialog *dialog, gpointer user_data),
		   gpointer user_data)
{
	ETrustPromptResponse response;
	GcrCertificateWidget *certificate_widget;
	GcrCertificate *certificate;
	GckAttributes *attributes;
	GtkWidget *dialog, *widget;
	GtkGrid *grid;
	const guchar *data;
	gchar *bhost, *tmp;
	gsize length;
	gint row = 0;

	dialog = gtk_dialog_new_with_buttons (
		_("Certificate trust..."), parent, GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
		_("_Cancel"), GTK_RESPONSE_CANCEL,
		_("_Reject"), GTK_RESPONSE_REJECT,
		_("Accept _Temporarily"), GTK_RESPONSE_YES,
		_("_Accept Permanently"), GTK_RESPONSE_ACCEPT,
		NULL);

	widget = gtk_dialog_get_content_area (GTK_DIALOG (dialog));

	gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);

	grid = g_object_new (
		GTK_TYPE_GRID,
		"orientation", GTK_ORIENTATION_HORIZONTAL,
		"row-homogeneous", FALSE,
		"row-spacing", 6,
		"column-homogeneous", FALSE,
		"column-spacing", 12,
		"hexpand", TRUE,
		"halign", GTK_ALIGN_FILL,
		"vexpand", TRUE,
		"valign", GTK_ALIGN_FILL,
		NULL);

	gtk_container_set_border_width (GTK_CONTAINER (grid), 5);
	gtk_container_add (GTK_CONTAINER (widget), GTK_WIDGET (grid));

	widget = gtk_image_new_from_icon_name ("dialog-warning", GTK_ICON_SIZE_DIALOG);
	g_object_set (
		G_OBJECT (widget),
		"vexpand", FALSE,
		"valign", GTK_ALIGN_START,
		NULL);
	gtk_grid_attach (grid, widget, 0, row, 1, 3);

	tmp = g_markup_escape_text (host, -1);
	bhost = g_strconcat ("<b>", tmp, "</b>", NULL);
	g_free (tmp);
	tmp = NULL;
	if (source_extension && source_display_name) {
		gchar *bsource_display_name = g_strconcat ("<b>", source_display_name, "</b>", NULL);

		if (g_str_equal (source_extension, E_SOURCE_EXTENSION_ADDRESS_BOOK)) {
			tmp = g_strdup_printf (
				"An address book '%s' cannot connect, because an SSL/TLS certificate for '%s' is not trusted. Do you wish to accept it?",
				bsource_display_name, bhost);
		} else if (g_str_equal (source_extension, E_SOURCE_EXTENSION_CALENDAR)) {
			tmp = g_strdup_printf (
				"A calendar '%s' cannot connect, because an SSL/TLS certificate for '%s' is not trusted. Do you wish to accept it?",
				bsource_display_name, bhost);
		} else if (g_str_equal (source_extension, E_SOURCE_EXTENSION_MEMO_LIST)) {
			tmp = g_strdup_printf (
				"A memo list '%s' cannot connect, because an SSL/TLS certificate for '%s' is not trusted. Do you wish to accept it?",
				bsource_display_name, bhost);
		} else if (g_str_equal (source_extension, E_SOURCE_EXTENSION_TASK_LIST)) {
			tmp = g_strdup_printf (
				"A task list '%s' cannot connect, because an SSL/TLS certificate for '%s' is not trusted. Do you wish to accept it?",
				bsource_display_name, bhost);
		} else if (g_str_equal (source_extension, E_SOURCE_EXTENSION_MAIL_ACCOUNT)) {
			tmp = g_strdup_printf (
				"A mail account '%s' cannot connect, because an SSL/TLS certificate for '%s' is not trusted. Do you wish to accept it?",
				bsource_display_name, bhost);
		} else if (g_str_equal (source_extension, E_SOURCE_EXTENSION_MAIL_TRANSPORT)) {
			tmp = g_strdup_printf (
				"A mail transport '%s' cannot connect, because an SSL/TLS certificate for '%s' is not trusted. Do you wish to accept it?",
				bsource_display_name, bhost);
		} else {
			tmp = g_strdup_printf (
				"An account '%s' cannot connect, because an SSL/TLS certificate for '%s' is not trusted. Do you wish to accept it?",
				bsource_display_name, bhost);
		}

		g_free (bsource_display_name);
	}
	if (!tmp)
		tmp = g_strdup_printf (_("SSL/TLS certificate for “%s” is not trusted. Do you wish to accept it?"), bhost);
	g_free (bhost);

	widget = gtk_label_new (NULL);
	gtk_label_set_line_wrap (GTK_LABEL (widget), TRUE);
	gtk_label_set_markup (GTK_LABEL (widget), tmp);
	g_object_set (
		G_OBJECT (widget),
		"hexpand", TRUE,
		"halign", GTK_ALIGN_FILL,
		"valign", GTK_ALIGN_CENTER,
		"width-chars", 60,
		"max-width-chars", 80,
		"xalign", 0.0,
		"yalign", 0.0,
		NULL);

	g_free (tmp);

	gtk_grid_attach (grid, widget, 1, row, 2, 1);
	row++;

	trust_prompt_add_info_line (grid, _("Reason:"), reason, FALSE, FALSE, TRUE, &row);

	if (error_text)
		trust_prompt_add_info_line (grid, _("Detailed error:"), error_text, FALSE, TRUE, FALSE, &row);

	data = gcr_parsed_get_data (parsed, &length);
	attributes = gcr_parsed_get_attributes (parsed);

	certificate = gcr_simple_certificate_new (data, length);

	certificate_widget = gcr_certificate_widget_new (certificate);
	gcr_certificate_widget_set_attributes (certificate_widget, attributes);

	widget = GTK_WIDGET (certificate_widget);
	gtk_grid_attach (grid, widget, 1, row, 2, 1);
	gtk_widget_show (widget);

	g_clear_object (&certificate);

	gtk_widget_show_all (GTK_WIDGET (grid));

	if (dialog_ready_cb)
		dialog_ready_cb (GTK_DIALOG (dialog), user_data);

	switch (gtk_dialog_run (GTK_DIALOG (dialog))) {
	case GTK_RESPONSE_REJECT:
		response = E_TRUST_PROMPT_RESPONSE_REJECT;
		break;
	case GTK_RESPONSE_ACCEPT:
		response = E_TRUST_PROMPT_RESPONSE_ACCEPT;
		break;
	case GTK_RESPONSE_YES:
		response = E_TRUST_PROMPT_RESPONSE_ACCEPT_TEMPORARILY;
		break;
	default:
		response = E_TRUST_PROMPT_RESPONSE_UNKNOWN;
		break;
	}

	gtk_widget_destroy (dialog);

	return response;
}