Compare commits

...
Author SHA1 Message Date
fa2e5d3293 cups: remember authentication with Secret Service
Look up and store CUPS authentication information through the Secret Service D-Bus API.

Enable the feature by default when CUPS support is built, requiring the libsecret development files unless explicitly disabled. Keep the print backend free of a runtime libsecret dependency so authentication continues to work when Secret Service is unavailable.
2026-08-12 19:38:55 +02:00
399e6ee64e cups: reduce authentication allocation overhead
Avoid unnecessary copies and heap allocations in the CUPS authentication paths.

Use borrowed strings where their lifetime is sufficient, use stack storage for the fixed password prompt fields, replace manual auth-info copying with g_strdupv(), and remove unused per-request hostname processing.

Also free auth_info_visible in request_auth_info().
2026-08-11 10:48:41 +02:00
3 changed files with 1085 additions and 78 deletions

View file

@ -1538,6 +1538,11 @@ LIBS="$old_LIBS"
# Printing system checks
################################################################
AC_ARG_ENABLE(cups-secret-service,
[AS_HELP_STRING([--disable-cups-secret-service]
[disable Secret Service support in the cups print backend])],,
[enable_cups_secret_service=yes])
AC_ARG_ENABLE(cups,
[AS_HELP_STRING([--disable-cups]
[disable cups print backend])],,
@ -1584,6 +1589,17 @@ else
AM_CONDITIONAL(HAVE_CUPS, true)
if test "x$enable_cups_secret_service" != "xno"; then
PKG_CHECK_EXISTS([libsecret-1], [],
[AC_MSG_ERROR([
*** libsecret-1 is required when CUPS Secret Service support is enabled.
*** Install the libsecret development files or configure
*** with --disable-cups-secret-service.
])])
AC_DEFINE([HAVE_CUPS_SECRET_SERVICE], [1],
[Define to 1 if CUPS Secret Service support is enabled])
fi
gtk_save_cflags="$CFLAGS"
CFLAGS="$CUPS_CFLAGS"
AC_COMPILE_IFELSE(

View file

@ -48,8 +48,22 @@ struct _GtkPrintBackendPrivate
GtkPrintBackendStatus status;
char **auth_info_required;
char **auth_info;
#ifdef HAVE_CUPS_SECRET_SERVICE
guint store_auth_info : 1;
#endif
};
#ifdef HAVE_CUPS_SECRET_SERVICE
typedef gboolean (*GtkPrintBackendCanStoreAuthInfoFunc)
(GtkPrintBackend *backend);
typedef void (*GtkPrintBackendSetPasswordFullFunc)
(GtkPrintBackend *backend,
gchar **auth_info_required,
gchar **auth_info,
gboolean store_auth_info);
#endif
enum {
PRINTER_LIST_CHANGED,
PRINTER_LIST_DONE,
@ -459,6 +473,9 @@ gtk_print_backend_init (GtkPrintBackend *backend)
(GDestroyNotify) g_object_unref);
priv->auth_info_required = NULL;
priv->auth_info = NULL;
#ifdef HAVE_CUPS_SECRET_SERVICE
priv->store_auth_info = FALSE;
#endif
}
static void
@ -675,6 +692,41 @@ gtk_print_backend_set_password (GtkPrintBackend *backend,
GTK_PRINT_BACKEND_GET_CLASS (backend)->set_password (backend, auth_info_required, auth_info);
}
#ifdef HAVE_CUPS_SECRET_SERVICE
static void
gtk_print_backend_set_password_full (GtkPrintBackend *backend,
gchar **auth_info_required,
gchar **auth_info,
gboolean store_auth_info)
{
GtkPrintBackendClass *class;
class = GTK_PRINT_BACKEND_GET_CLASS (backend);
if (class->_gtk_reserved2 != NULL)
((GtkPrintBackendSetPasswordFullFunc) class->_gtk_reserved2)
(backend,
auth_info_required,
auth_info,
store_auth_info);
else
gtk_print_backend_set_password (backend,
auth_info_required,
auth_info);
}
static void
store_auth_info_toggled (GtkToggleButton *button,
GtkPrintBackend *backend)
{
backend->priv->store_auth_info =
gtk_toggle_button_get_active (button);
}
#endif
static void
store_entry (GtkEntry *entry,
gpointer user_data)
@ -698,10 +750,23 @@ password_dialog_response (GtkWidget *dialog,
GtkPrintBackendPrivate *priv = backend->priv;
gint i;
#ifdef HAVE_CUPS_SECRET_SERVICE
if (response_id == GTK_RESPONSE_OK)
gtk_print_backend_set_password_full (backend,
priv->auth_info_required,
priv->auth_info,
priv->store_auth_info);
else
gtk_print_backend_set_password_full (backend,
priv->auth_info_required,
NULL,
FALSE);
#else
if (response_id == GTK_RESPONSE_OK)
gtk_print_backend_set_password (backend, priv->auth_info_required, priv->auth_info);
else
gtk_print_backend_set_password (backend, priv->auth_info_required, NULL);
#endif
for (i = 0; i < g_strv_length (priv->auth_info_required); i++)
if (priv->auth_info[i] != NULL)
@ -738,10 +803,23 @@ request_password (GtkPrintBackend *backend,
gchar **ai_default = (gchar **) auth_info_default;
gchar **ai_display = (gchar **) auth_info_display;
gboolean *ai_visible = (gboolean *) auth_info_visible;
#ifdef HAVE_CUPS_SECRET_SERVICE
GtkPrintBackendClass *class;
gboolean can_store_auth_info = FALSE;
#endif
priv->auth_info_required = g_strdupv (ai_required);
length = g_strv_length (ai_required);
priv->auth_info = g_new0 (gchar *, length + 1);
#ifdef HAVE_CUPS_SECRET_SERVICE
priv->store_auth_info = FALSE;
class = GTK_PRINT_BACKEND_GET_CLASS (backend);
if (class->_gtk_reserved1 != NULL)
can_store_auth_info =
((GtkPrintBackendCanStoreAuthInfoFunc) class->_gtk_reserved1)
(backend);
#endif
dialog = gtk_dialog_new_with_buttons ( _("Authentication"), NULL, GTK_DIALOG_MODAL,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
@ -810,6 +888,18 @@ request_password (GtkPrintBackend *backend,
}
}
#ifdef HAVE_CUPS_SECRET_SERVICE
if (can_store_auth_info)
{
GtkWidget *remember;
remember = gtk_check_button_new_with_mnemonic (_("_Remember password"));
gtk_box_pack_start (GTK_BOX (vbox), remember, FALSE, FALSE, 6);
g_signal_connect (remember, "toggled",
G_CALLBACK (store_auth_info_toggled), backend);
}
#endif
if (focus != NULL)
{
gtk_widget_grab_focus (focus);

File diff suppressed because it is too large Load diff