/* Licensed to Stichting The Commons Conservancy (TCC) under one or more * contributor license agreements. See the AUTHORS file distributed with * this work for additional information regarding copyright ownership. * TCC licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include "signtext.h" GQuark rst_core_error_quark (void) { static GQuark quark; if (!quark) { quark = g_quark_from_static_string ("rst-core-error-quark"); } return quark; } SignTextData *signtext_data_new() { SignTextData *signtext = g_new (SignTextData, 1); memset(signtext, 0, sizeof(SignTextData)); signtext->incoming = g_list_store_new(GCR_TYPE_CERTIFICATE); signtext->certificates = g_list_store_new(GCR_TYPE_CERTIFICATE); return signtext; } void signtext_data_free(SignTextData *data) { if (data) { if (data->incoming) g_object_unref(data->incoming); if (data->certificates) g_object_unref(data->certificates); if (data->modules) g_list_free_full (g_steal_pointer (&data->modules), g_object_unref); if (data->slots) g_list_free_full (g_steal_pointer (&data->slots), g_object_unref); } g_free(data); } SignTextToken *signtext_token_new() { SignTextToken *token = g_new (SignTextToken, 1); memset(token, 0, sizeof(SignTextToken)); return token; } void signtext_token_free(SignTextToken *signtext_token) { if (signtext_token->token_info) gck_token_info_free(signtext_token->token_info); g_free(signtext_token); } static char * get_certificate_display_name (GcrCertificate *certificate) { GDateTime *expiry = gcr_certificate_get_expiry_date(certificate); char *display; char *exp = NULL; if (expiry) { exp = g_date_time_format(expiry, (const gchar*)"%d %B %Y"); } #if 0 if (exp) { display = g_markup_printf_escaped ("%s\r%s\r%s", gcr_certificate_get_subject_name (certificate), gcr_certificate_get_issuer_name (certificate), exp); } else { display = g_markup_printf_escaped ("%s\r%s", gcr_certificate_get_subject_name (certificate), gcr_certificate_get_issuer_name (certificate)); } #else /* workaround until https://gitlab.gnome.org/GNOME/libadwaita/-/issues/849 is fixed */ if (exp) { display = g_strdup_printf ("%s\rIssuer: %s\rExpiry: %s", gcr_certificate_get_subject_name (certificate), gcr_certificate_get_issuer_name (certificate), exp); } else { display = g_strdup_printf ("%s\rIssuer: %s", gcr_certificate_get_subject_name (certificate), gcr_certificate_get_issuer_name (certificate)); } #endif if (exp) { g_free(exp); } if (expiry) { // g_date_time_unref(expiry); } return display; } SignTextInstance *signtext_instance_new(SignTextData *signtext, gint64 id, const gchar *uuid, GUri *uri) { GtkExpression *expression; SignTextInstance *instance = g_new (SignTextInstance, 1); memset(instance, 0, sizeof(SignTextInstance)); instance->signtext = signtext; g_uri_ref(uri); instance->id = id; instance->uuid = g_strdup(uuid); instance->uri = uri; instance->detached = TRUE; instance->page = ADW_PREFERENCES_PAGE(adw_preferences_page_new()); instance->textgroup = ADW_PREFERENCES_GROUP(adw_preferences_group_new()); adw_preferences_page_add (ADW_PREFERENCES_PAGE(instance->page), ADW_PREFERENCES_GROUP(instance->textgroup)); instance->buffer = gtk_text_buffer_new (gtk_text_tag_table_new ()); instance->textviewrow = GTK_TEXT_VIEW (gtk_text_view_new_with_buffer(instance->buffer)); gtk_text_view_set_editable(instance->textviewrow, FALSE); gtk_text_view_set_cursor_visible(instance->textviewrow, FALSE); gtk_text_view_set_wrap_mode(instance->textviewrow, GTK_WRAP_WORD_CHAR); gtk_widget_set_vexpand (GTK_WIDGET(instance->textviewrow), 1); gtk_widget_set_valign (GTK_WIDGET(instance->textviewrow), GTK_ALIGN_FILL); gtk_widget_set_visible(GTK_WIDGET(instance->textviewrow), TRUE); instance->scrolled = GTK_SCROLLED_WINDOW (gtk_scrolled_window_new ()); gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW(instance->scrolled), GTK_WIDGET(instance->textviewrow)); adw_preferences_group_add (ADW_PREFERENCES_GROUP(instance->textgroup), GTK_WIDGET(instance->scrolled)); adw_preferences_group_set_description(ADW_PREFERENCES_GROUP(instance->textgroup), g_markup_printf_escaped("The site %s has requested you sign the following text message.", g_uri_get_host(instance->uri))); instance->signgroup = ADW_PREFERENCES_GROUP(adw_preferences_group_new()); adw_preferences_page_add (ADW_PREFERENCES_PAGE(instance->page), ADW_PREFERENCES_GROUP(instance->signgroup)); /* * Work around adw combo row lack of support for pango markup in dropdowns. */ expression = gtk_cclosure_expression_new (G_TYPE_STRING, NULL, 0, NULL, G_CALLBACK (get_certificate_display_name), instance, NULL); instance->selectorrow = ADW_COMBO_ROW(adw_combo_row_new()); adw_combo_row_set_expression (ADW_COMBO_ROW(instance->selectorrow), expression); adw_combo_row_set_use_subtitle(ADW_COMBO_ROW(instance->selectorrow), TRUE); #if 0 /* disabled until https://gitlab.gnome.org/GNOME/libadwaita/-/issues/849 is fixed */ adw_preferences_row_set_use_markup(ADW_PREFERENCES_ROW(instance->selectorrow), TRUE); #endif adw_preferences_group_add (ADW_PREFERENCES_GROUP(instance->signgroup), GTK_WIDGET(instance->selectorrow)); instance->pinrow = ADW_PASSWORD_ENTRY_ROW (adw_password_entry_row_new()); instance->pinicon = GTK_IMAGE(gtk_image_new()); adw_entry_row_add_suffix(ADW_ENTRY_ROW(instance->pinrow), GTK_WIDGET(instance->pinicon)); gtk_widget_set_sensitive(GTK_WIDGET(instance->pinrow), FALSE); adw_preferences_group_add (ADW_PREFERENCES_GROUP(instance->signgroup), GTK_WIDGET(instance->pinrow)); adw_preferences_group_set_description(ADW_PREFERENCES_GROUP(instance->signgroup), "If you agree with the text message above, and are happy with the identity of the site, select a certificate and enter your PIN."); instance->progress = GTK_PROGRESS_BAR(gtk_progress_bar_new()); gtk_widget_set_visible(GTK_WIDGET(instance->progress), FALSE); instance->overlay = GTK_OVERLAY(gtk_overlay_new()); gtk_overlay_set_child (GTK_OVERLAY(instance->overlay), GTK_WIDGET (instance->page)); gtk_overlay_add_overlay (GTK_OVERLAY(instance->overlay), GTK_WIDGET (instance->progress)); g_object_set_data_full(G_OBJECT (signtext->stack), instance->uuid, instance, (GDestroyNotify)signtext_instance_free); adw_view_stack_add_titled(signtext->stack, GTK_WIDGET (instance->overlay), instance->uuid, g_uri_get_host(instance->uri)); // instance->stack = signtext->stack; return instance; } void signtext_instance_free(SignTextInstance *instance) { if (instance) { adw_view_stack_remove(instance->signtext->stack, GTK_WIDGET (instance->overlay)); if (!adw_view_stack_get_visible_child_name(instance->signtext->stack)) { gtk_widget_set_visible (GTK_WIDGET(instance->signtext->window), 0); #if 0 gtk_widget_destroy(instance->signtext->window); #endif } g_object_steal_data(G_OBJECT (instance->signtext->stack), instance->uuid); if (instance->uuid) g_free(instance->uuid); if (instance->uri) g_uri_unref(instance->uri); if (instance->w) { ksba_writer_release(instance->w); } if (instance->cas) { g_list_foreach(instance->cas, (GFunc)g_bytes_unref, NULL); g_list_free (instance->cas); } } g_free(instance); } /* * Display the error dialog. * * Switch off the progress bar, if it is running. */ void signtext_error(SignTextInstance *instance, GError *gerror) { AdwDialog* dialog; if (instance) { gtk_widget_set_visible(GTK_WIDGET(instance->progress), FALSE); // gtk_widget_set_sensitive(GTK_WIDGET(instance->selectorrow), TRUE); // gtk_widget_set_sensitive(GTK_WIDGET(instance->sign), TRUE); } dialog = adw_alert_dialog_new ("Redwax SignText - Error", NULL); adw_alert_dialog_format_body (ADW_ALERT_DIALOG (dialog), ("Error: %s"), gerror->message); adw_alert_dialog_add_response(ADW_ALERT_DIALOG (dialog), "Ok", "Ok"); adw_dialog_present (dialog, instance->signtext->window); }