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.
This commit is contained in:
Daemonratte 2026-08-12 19:38:55 +02:00
commit fa2e5d3293
3 changed files with 1047 additions and 0 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