771 lines
30 KiB
Diff
771 lines
30 KiB
Diff
|
From 82562ae5ddd7e50428aaedb5eb1edeec57c3f54f Mon Sep 17 00:00:00 2001
|
||
|
From: Marek Kasik <mkasik@redhat.com>
|
||
|
Date: Wed, 16 Sep 2009 14:54:05 +0200
|
||
|
Subject: [PATCH] Add support for 'auth-info' attribute to the CUPS backend
|
||
|
|
||
|
Check for 'auth-info-required' attribute from printer attributes to
|
||
|
find out whether an authentization of user is needed.
|
||
|
Change password dialog of print backend to be able to require informations
|
||
|
requested thru 'auth-info-required' (#566522).
|
||
|
---
|
||
|
gtk/gtkmarshalers.list | 1 +
|
||
|
gtk/gtkprintbackend.c | 164 +++++++-------
|
||
|
gtk/gtkprintbackend.h | 16 +-
|
||
|
modules/printbackends/cups/gtkcupsutils.c | 5 +
|
||
|
modules/printbackends/cups/gtkcupsutils.h | 3 +
|
||
|
modules/printbackends/cups/gtkprintbackendcups.c | 255 ++++++++++++++++++++--
|
||
|
modules/printbackends/cups/gtkprintercups.c | 2 +
|
||
|
modules/printbackends/cups/gtkprintercups.h | 1 +
|
||
|
8 files changed, 339 insertions(+), 108 deletions(-)
|
||
|
|
||
|
diff --git a/gtk/gtkmarshalers.list b/gtk/gtkmarshalers.list
|
||
|
index 533a266..77873cb 100644
|
||
|
--- a/gtk/gtkmarshalers.list
|
||
|
+++ b/gtk/gtkmarshalers.list
|
||
|
@@ -111,3 +111,4 @@ VOID:UINT,STRING,UINT
|
||
|
VOID:UINT,UINT
|
||
|
VOID:VOID
|
||
|
OBJECT:OBJECT,INT,INT
|
||
|
+VOID:POINTER,POINTER,POINTER,POINTER,STRING
|
||
|
diff --git a/gtk/gtkprintbackend.c b/gtk/gtkprintbackend.c
|
||
|
index 567273b..3c64823 100644
|
||
|
--- a/gtk/gtkprintbackend.c
|
||
|
+++ b/gtk/gtkprintbackend.c
|
||
|
@@ -50,9 +50,8 @@ struct _GtkPrintBackendPrivate
|
||
|
guint printer_list_requested : 1;
|
||
|
guint printer_list_done : 1;
|
||
|
GtkPrintBackendStatus status;
|
||
|
- char *hostname;
|
||
|
- char *username;
|
||
|
- char *password;
|
||
|
+ char **auth_info_required;
|
||
|
+ char **auth_info;
|
||
|
};
|
||
|
|
||
|
enum {
|
||
|
@@ -359,8 +358,10 @@ static GList * fallback_printer_list_papers (GtkPrinter
|
||
|
static GtkPageSetup * fallback_printer_get_default_page_size (GtkPrinter *printer);
|
||
|
static GtkPrintCapabilities fallback_printer_get_capabilities (GtkPrinter *printer);
|
||
|
static void request_password (GtkPrintBackend *backend,
|
||
|
- const gchar *hostname,
|
||
|
- const gchar *username,
|
||
|
+ gpointer auth_info_required,
|
||
|
+ gpointer auth_info_default,
|
||
|
+ gpointer auth_info_display,
|
||
|
+ gpointer auth_info_visible,
|
||
|
const gchar *prompt);
|
||
|
|
||
|
static void
|
||
|
@@ -441,8 +442,8 @@ gtk_print_backend_class_init (GtkPrintBackendClass *class)
|
||
|
G_SIGNAL_RUN_LAST,
|
||
|
G_STRUCT_OFFSET (GtkPrintBackendClass, request_password),
|
||
|
NULL, NULL,
|
||
|
- _gtk_marshal_VOID__STRING_STRING_STRING,
|
||
|
- G_TYPE_NONE, 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
|
||
|
+ _gtk_marshal_VOID__POINTER_POINTER_POINTER_POINTER_STRING,
|
||
|
+ G_TYPE_NONE, 5, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_STRING);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
@@ -455,9 +456,8 @@ gtk_print_backend_init (GtkPrintBackend *backend)
|
||
|
priv->printers = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||
|
(GDestroyNotify) g_free,
|
||
|
(GDestroyNotify) g_object_unref);
|
||
|
- priv->hostname = NULL;
|
||
|
- priv->username = NULL;
|
||
|
- priv->password = NULL;
|
||
|
+ priv->auth_info_required = NULL;
|
||
|
+ priv->auth_info = NULL;
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
@@ -662,40 +662,29 @@ gtk_print_backend_print_stream (GtkPrintBackend *backend,
|
||
|
}
|
||
|
|
||
|
void
|
||
|
-gtk_print_backend_set_password (GtkPrintBackend *backend,
|
||
|
- const gchar *hostname,
|
||
|
- const gchar *username,
|
||
|
- const gchar *password)
|
||
|
+gtk_print_backend_set_password (GtkPrintBackend *backend,
|
||
|
+ gchar **auth_info_required,
|
||
|
+ gchar **auth_info)
|
||
|
{
|
||
|
g_return_if_fail (GTK_IS_PRINT_BACKEND (backend));
|
||
|
|
||
|
if (GTK_PRINT_BACKEND_GET_CLASS (backend)->set_password)
|
||
|
- GTK_PRINT_BACKEND_GET_CLASS (backend)->set_password (backend, hostname, username, password);
|
||
|
+ GTK_PRINT_BACKEND_GET_CLASS (backend)->set_password (backend, auth_info_required, auth_info);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
-store_password (GtkEntry *entry,
|
||
|
- GtkPrintBackend *backend)
|
||
|
+store_entry (GtkEntry *entry,
|
||
|
+ gpointer user_data)
|
||
|
{
|
||
|
- GtkPrintBackendPrivate *priv = backend->priv;
|
||
|
+ gchar **data = (gchar **) user_data;
|
||
|
|
||
|
- if (priv->password != NULL)
|
||
|
+ if (*data != NULL)
|
||
|
{
|
||
|
- memset (priv->password, 0, strlen (priv->password));
|
||
|
- g_free (priv->password);
|
||
|
+ memset (*data, 0, strlen (*data));
|
||
|
+ g_free (*data);
|
||
|
}
|
||
|
|
||
|
- priv->password = g_strdup (gtk_entry_get_text (entry));
|
||
|
-}
|
||
|
-
|
||
|
-static void
|
||
|
-store_username (GtkEntry *entry,
|
||
|
- GtkPrintBackend *backend)
|
||
|
-{
|
||
|
- GtkPrintBackendPrivate *priv = backend->priv;
|
||
|
-
|
||
|
- g_free (priv->username);
|
||
|
- priv->username = g_strdup (gtk_entry_get_text (entry));
|
||
|
+ *data = g_strdup (gtk_entry_get_text (entry));
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
@@ -704,21 +693,24 @@ password_dialog_response (GtkWidget *dialog,
|
||
|
GtkPrintBackend *backend)
|
||
|
{
|
||
|
GtkPrintBackendPrivate *priv = backend->priv;
|
||
|
+ gint i;
|
||
|
|
||
|
if (response_id == GTK_RESPONSE_OK)
|
||
|
- gtk_print_backend_set_password (backend, priv->hostname, priv->username, priv->password);
|
||
|
+ gtk_print_backend_set_password (backend, priv->auth_info_required, priv->auth_info);
|
||
|
else
|
||
|
- gtk_print_backend_set_password (backend, priv->hostname, priv->username, NULL);
|
||
|
+ gtk_print_backend_set_password (backend, priv->auth_info_required, NULL);
|
||
|
|
||
|
- if (priv->password != NULL)
|
||
|
- {
|
||
|
- memset (priv->password, 0, strlen (priv->password));
|
||
|
- g_free (priv->password);
|
||
|
- priv->password = NULL;
|
||
|
- }
|
||
|
+ for (i = 0; i < g_strv_length (priv->auth_info_required); i++)
|
||
|
+ if (priv->auth_info[i] != NULL)
|
||
|
+ {
|
||
|
+ memset (priv->auth_info[i], 0, strlen (priv->auth_info[i]));
|
||
|
+ g_free (priv->auth_info[i]);
|
||
|
+ priv->auth_info[i] = NULL;
|
||
|
+ }
|
||
|
+ g_free (priv->auth_info);
|
||
|
+ priv->auth_info = NULL;
|
||
|
|
||
|
- g_free (priv->username);
|
||
|
- priv->username = NULL;
|
||
|
+ g_strfreev (priv->auth_info_required);
|
||
|
|
||
|
gtk_widget_destroy (dialog);
|
||
|
|
||
|
@@ -726,16 +718,27 @@ password_dialog_response (GtkWidget *dialog,
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
-request_password (GtkPrintBackend *backend,
|
||
|
- const gchar *hostname,
|
||
|
- const gchar *username,
|
||
|
- const gchar *prompt)
|
||
|
+request_password (GtkPrintBackend *backend,
|
||
|
+ gpointer auth_info_required,
|
||
|
+ gpointer auth_info_default,
|
||
|
+ gpointer auth_info_display,
|
||
|
+ gpointer auth_info_visible,
|
||
|
+ const gchar *prompt)
|
||
|
{
|
||
|
GtkPrintBackendPrivate *priv = backend->priv;
|
||
|
- GtkWidget *dialog, *username_box, *password_box, *main_box, *label, *icon, *vbox,
|
||
|
- *password_prompt, *username_prompt,
|
||
|
- *password_entry, *username_entry;
|
||
|
+ GtkWidget *dialog, *box, *main_box, *label, *icon, *vbox, *entry;
|
||
|
+ GtkWidget *focus = NULL;
|
||
|
gchar *markup;
|
||
|
+ gint length;
|
||
|
+ gint i;
|
||
|
+ gchar **ai_required = (gchar **) auth_info_required;
|
||
|
+ gchar **ai_default = (gchar **) auth_info_default;
|
||
|
+ gchar **ai_display = (gchar **) auth_info_display;
|
||
|
+ gboolean *ai_visible = (gboolean *) auth_info_visible;
|
||
|
+
|
||
|
+ priv->auth_info_required = g_strdupv (ai_required);
|
||
|
+ length = g_strv_length (ai_required);
|
||
|
+ priv->auth_info = g_new0 (gchar *, length);
|
||
|
|
||
|
dialog = gtk_dialog_new_with_buttons ( _("Authentication"), NULL, GTK_DIALOG_MODAL,
|
||
|
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||
|
@@ -766,27 +769,6 @@ request_password (GtkPrintBackend *backend,
|
||
|
g_free (markup);
|
||
|
|
||
|
|
||
|
- /* Right - 2. */
|
||
|
- username_box = gtk_hbox_new (TRUE, 0);
|
||
|
-
|
||
|
- username_prompt = gtk_label_new (_("Username:"));
|
||
|
- gtk_misc_set_alignment (GTK_MISC (username_prompt), 0.0, 0.5);
|
||
|
-
|
||
|
- username_entry = gtk_entry_new ();
|
||
|
- gtk_entry_set_text (GTK_ENTRY (username_entry), username);
|
||
|
-
|
||
|
-
|
||
|
- /* Right - 3. */
|
||
|
- password_box = gtk_hbox_new (TRUE, 0);
|
||
|
-
|
||
|
- password_prompt = gtk_label_new (_("Password:"));
|
||
|
- gtk_misc_set_alignment (GTK_MISC (password_prompt), 0.0, 0.5);
|
||
|
-
|
||
|
- password_entry = gtk_entry_new ();
|
||
|
- gtk_entry_set_visibility (GTK_ENTRY (password_entry), FALSE);
|
||
|
- gtk_entry_set_activates_default (GTK_ENTRY (password_entry), TRUE);
|
||
|
-
|
||
|
-
|
||
|
/* Packing */
|
||
|
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), main_box, TRUE, FALSE, 0);
|
||
|
|
||
|
@@ -794,26 +776,42 @@ request_password (GtkPrintBackend *backend,
|
||
|
gtk_box_pack_start (GTK_BOX (main_box), vbox, FALSE, FALSE, 6);
|
||
|
|
||
|
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, TRUE, 6);
|
||
|
- gtk_box_pack_start (GTK_BOX (vbox), username_box, FALSE, TRUE, 6);
|
||
|
- gtk_box_pack_start (GTK_BOX (vbox), password_box, FALSE, TRUE, 6);
|
||
|
+
|
||
|
+ /* Right - 2. */
|
||
|
+ for (i = 0; i < length; i++)
|
||
|
+ {
|
||
|
+ priv->auth_info[i] = g_strdup (ai_default[i]);
|
||
|
+ if (ai_display[i] != NULL)
|
||
|
+ {
|
||
|
+ box = gtk_hbox_new (TRUE, 0);
|
||
|
+
|
||
|
+ label = gtk_label_new (ai_display[i]);
|
||
|
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
|
||
|
|
||
|
- gtk_box_pack_start (GTK_BOX (username_box), username_prompt, TRUE, TRUE, 0);
|
||
|
- gtk_box_pack_start (GTK_BOX (username_box), username_entry, TRUE, TRUE, 0);
|
||
|
+ entry = gtk_entry_new ();
|
||
|
+ focus = entry;
|
||
|
|
||
|
- gtk_box_pack_start (GTK_BOX (password_box), password_prompt, TRUE, TRUE, 0);
|
||
|
- gtk_box_pack_start (GTK_BOX (password_box), password_entry, TRUE, TRUE, 0);
|
||
|
+ if (ai_default[i] != NULL)
|
||
|
+ gtk_entry_set_text (GTK_ENTRY (entry), ai_default[i]);
|
||
|
|
||
|
+ gtk_entry_set_visibility (GTK_ENTRY (entry), ai_visible[i]);
|
||
|
+ gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
|
||
|
|
||
|
- gtk_widget_grab_focus (password_entry);
|
||
|
+ gtk_box_pack_start (GTK_BOX (vbox), box, FALSE, TRUE, 6);
|
||
|
|
||
|
- priv->hostname = g_strdup (hostname);
|
||
|
- priv->username = g_strdup (username);
|
||
|
+ gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 0);
|
||
|
+ gtk_box_pack_start (GTK_BOX (box), entry, TRUE, TRUE, 0);
|
||
|
|
||
|
- g_signal_connect (password_entry, "changed",
|
||
|
- G_CALLBACK (store_password), backend);
|
||
|
+ g_signal_connect (entry, "changed",
|
||
|
+ G_CALLBACK (store_entry), &(priv->auth_info[i]));
|
||
|
+ }
|
||
|
+ }
|
||
|
|
||
|
- g_signal_connect (username_entry, "changed",
|
||
|
- G_CALLBACK (store_username), backend);
|
||
|
+ if (focus != NULL)
|
||
|
+ {
|
||
|
+ gtk_widget_grab_focus (focus);
|
||
|
+ focus = NULL;
|
||
|
+ }
|
||
|
|
||
|
g_object_ref (backend);
|
||
|
g_signal_connect (G_OBJECT (dialog), "response",
|
||
|
diff --git a/gtk/gtkprintbackend.h b/gtk/gtkprintbackend.h
|
||
|
index 7d75f8e..c4b43b1 100644
|
||
|
--- a/gtk/gtkprintbackend.h
|
||
|
+++ b/gtk/gtkprintbackend.h
|
||
|
@@ -121,15 +121,16 @@ struct _GtkPrintBackendClass
|
||
|
void (*printer_status_changed) (GtkPrintBackend *backend,
|
||
|
GtkPrinter *printer);
|
||
|
void (*request_password) (GtkPrintBackend *backend,
|
||
|
- const gchar *hostname,
|
||
|
- const gchar *username,
|
||
|
+ gpointer auth_info_required,
|
||
|
+ gpointer auth_info_default,
|
||
|
+ gpointer auth_info_display,
|
||
|
+ gpointer auth_info_visible,
|
||
|
const gchar *prompt);
|
||
|
|
||
|
/* not a signal */
|
||
|
void (*set_password) (GtkPrintBackend *backend,
|
||
|
- const gchar *hostname,
|
||
|
- const gchar *username,
|
||
|
- const gchar *password);
|
||
|
+ gchar **auth_info_required,
|
||
|
+ gchar **auth_info);
|
||
|
|
||
|
/* Padding for future expansion */
|
||
|
void (*_gtk_reserved1) (void);
|
||
|
@@ -153,9 +154,8 @@ void gtk_print_backend_print_stream (GtkPrintBackend *pri
|
||
|
GList * gtk_print_backend_load_modules (void);
|
||
|
void gtk_print_backend_destroy (GtkPrintBackend *print_backend);
|
||
|
void gtk_print_backend_set_password (GtkPrintBackend *backend,
|
||
|
- const gchar *hostname,
|
||
|
- const gchar *username,
|
||
|
- const gchar *password);
|
||
|
+ gchar **auth_info_required,
|
||
|
+ gchar **auth_info);
|
||
|
|
||
|
/* Backend-only functions for GtkPrintBackend */
|
||
|
|
||
|
diff --git a/modules/printbackends/cups/gtkcupsutils.c b/modules/printbackends/cups/gtkcupsutils.c
|
||
|
index bcd03dc..cd97f10 100644
|
||
|
--- a/modules/printbackends/cups/gtkcupsutils.c
|
||
|
+++ b/modules/printbackends/cups/gtkcupsutils.c
|
||
|
@@ -187,6 +187,10 @@ gtk_cups_request_new_with_username (http_t *connection,
|
||
|
"requesting-user-name",
|
||
|
NULL, cupsUser ());
|
||
|
|
||
|
+ request->auth_info_required = NULL;
|
||
|
+ request->auth_info = NULL;
|
||
|
+ request->need_auth_info = FALSE;
|
||
|
+
|
||
|
cupsLangFree (language);
|
||
|
|
||
|
return request;
|
||
|
@@ -241,6 +245,7 @@ gtk_cups_request_free (GtkCupsRequest *request)
|
||
|
}
|
||
|
|
||
|
g_free (request->username);
|
||
|
+ g_strfreev (request->auth_info_required);
|
||
|
|
||
|
gtk_cups_result_free (request->result);
|
||
|
|
||
|
diff --git a/modules/printbackends/cups/gtkcupsutils.h b/modules/printbackends/cups/gtkcupsutils.h
|
||
|
index 47fd106..ba43f87 100644
|
||
|
--- a/modules/printbackends/cups/gtkcupsutils.h
|
||
|
+++ b/modules/printbackends/cups/gtkcupsutils.h
|
||
|
@@ -99,6 +99,9 @@ struct _GtkCupsRequest
|
||
|
|
||
|
gint own_http : 1;
|
||
|
gint need_password : 1;
|
||
|
+ gint need_auth_info : 1;
|
||
|
+ gchar **auth_info_required;
|
||
|
+ gchar **auth_info;
|
||
|
GtkCupsPasswordState password_state;
|
||
|
};
|
||
|
|
||
|
diff --git a/modules/printbackends/cups/gtkprintbackendcups.c b/modules/printbackends/cups/gtkprintbackendcups.c
|
||
|
index 92d4b9b..b715817 100644
|
||
|
--- a/modules/printbackends/cups/gtkprintbackendcups.c
|
||
|
+++ b/modules/printbackends/cups/gtkprintbackendcups.c
|
||
|
@@ -94,6 +94,8 @@ typedef struct
|
||
|
GtkCupsRequest *request;
|
||
|
GPollFD *data_poll;
|
||
|
GtkPrintBackendCups *backend;
|
||
|
+ GtkPrintCupsResponseCallbackFunc callback;
|
||
|
+ gpointer callback_data;
|
||
|
|
||
|
} GtkPrintCupsDispatchWatch;
|
||
|
|
||
|
@@ -179,13 +181,13 @@ static cairo_surface_t * cups_printer_create_cairo_surface (GtkPrinter
|
||
|
gdouble height,
|
||
|
GIOChannel *cache_io);
|
||
|
|
||
|
-static void gtk_print_backend_cups_set_password (GtkPrintBackend *backend,
|
||
|
- const gchar *hostname,
|
||
|
- const gchar *username,
|
||
|
- const gchar *password);
|
||
|
+static void gtk_print_backend_cups_set_password (GtkPrintBackend *backend,
|
||
|
+ gchar **auth_info_required,
|
||
|
+ gchar **auth_info);
|
||
|
|
||
|
-void overwrite_and_free (gpointer data);
|
||
|
-static gboolean is_address_local (const gchar *address);
|
||
|
+void overwrite_and_free (gpointer data);
|
||
|
+static gboolean is_address_local (const gchar *address);
|
||
|
+static gboolean request_auth_info (gpointer data);
|
||
|
|
||
|
static void
|
||
|
gtk_print_backend_cups_register_type (GTypeModule *module)
|
||
|
@@ -557,6 +559,9 @@ gtk_print_backend_cups_print_stream (GtkPrintBackend *print_backend,
|
||
|
ps->dnotify = dnotify;
|
||
|
ps->job = g_object_ref (job);
|
||
|
|
||
|
+ request->need_auth_info = cups_printer->auth_info_required != NULL;
|
||
|
+ request->auth_info_required = g_strdupv (cups_printer->auth_info_required);
|
||
|
+
|
||
|
cups_request_execute (GTK_PRINT_BACKEND_CUPS (print_backend),
|
||
|
request,
|
||
|
(GtkPrintCupsResponseCallbackFunc) cups_print_cb,
|
||
|
@@ -656,18 +661,38 @@ is_address_local (const gchar *address)
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
-gtk_print_backend_cups_set_password (GtkPrintBackend *backend,
|
||
|
- const gchar *hostname,
|
||
|
- const gchar *username,
|
||
|
- const gchar *password)
|
||
|
+gtk_print_backend_cups_set_password (GtkPrintBackend *backend,
|
||
|
+ gchar **auth_info_required,
|
||
|
+ gchar **auth_info)
|
||
|
{
|
||
|
GtkPrintBackendCups *cups_backend = GTK_PRINT_BACKEND_CUPS (backend);
|
||
|
GList *l;
|
||
|
char dispatch_hostname[HTTP_MAX_URI];
|
||
|
gchar *key;
|
||
|
+ gchar *username = NULL;
|
||
|
+ gchar *hostname = NULL;
|
||
|
+ gchar *password = NULL;
|
||
|
+ gint length;
|
||
|
+ gint i;
|
||
|
|
||
|
- key = g_strconcat (username, "@", hostname, NULL);
|
||
|
- g_hash_table_insert (cups_backend->auth, key, g_strdup (password));
|
||
|
+ length = g_strv_length (auth_info_required);
|
||
|
+
|
||
|
+ if (auth_info != NULL)
|
||
|
+ for (i = 0; i < length; i++)
|
||
|
+ {
|
||
|
+ if (g_strcmp0 (auth_info_required[i], "username") == 0)
|
||
|
+ username = g_strdup (auth_info[i]);
|
||
|
+ else if (g_strcmp0 (auth_info_required[i], "hostname") == 0)
|
||
|
+ hostname = g_strdup (auth_info[i]);
|
||
|
+ else if (g_strcmp0 (auth_info_required[i], "password") == 0)
|
||
|
+ password = g_strdup (auth_info[i]);
|
||
|
+ }
|
||
|
+
|
||
|
+ if (hostname != NULL && username != NULL && password != NULL)
|
||
|
+ {
|
||
|
+ key = g_strconcat (username, "@", hostname, NULL);
|
||
|
+ g_hash_table_insert (cups_backend->auth, key, g_strdup (password));
|
||
|
+ }
|
||
|
|
||
|
g_free (cups_backend->username);
|
||
|
cups_backend->username = g_strdup (username);
|
||
|
@@ -683,7 +708,18 @@ gtk_print_backend_cups_set_password (GtkPrintBackend *backend,
|
||
|
if (is_address_local (dispatch_hostname))
|
||
|
strcpy (dispatch_hostname, "localhost");
|
||
|
|
||
|
- if (strcmp (hostname, dispatch_hostname) == 0)
|
||
|
+ if (dispatch->request->need_auth_info)
|
||
|
+ {
|
||
|
+ if (auth_info != NULL)
|
||
|
+ {
|
||
|
+ dispatch->request->auth_info = g_new0 (gchar *, length + 1);
|
||
|
+ for (i = 0; i < length; i++)
|
||
|
+ dispatch->request->auth_info[i] = g_strdup (auth_info[i]);
|
||
|
+ }
|
||
|
+ dispatch->backend->authentication_lock = FALSE;
|
||
|
+ dispatch->request->need_auth_info = FALSE;
|
||
|
+ }
|
||
|
+ else if (dispatch->request->password_state == GTK_CUPS_PASSWORD_REQUESTED || auth_info == NULL)
|
||
|
{
|
||
|
overwrite_and_free (dispatch->request->password);
|
||
|
dispatch->request->password = g_strdup (password);
|
||
|
@@ -704,6 +740,12 @@ request_password (gpointer data)
|
||
|
gchar *prompt = NULL;
|
||
|
gchar *key = NULL;
|
||
|
char hostname[HTTP_MAX_URI];
|
||
|
+ gchar **auth_info_required;
|
||
|
+ gchar **auth_info_default;
|
||
|
+ gchar **auth_info_display;
|
||
|
+ gboolean *auth_info_visible;
|
||
|
+ gint length = 3;
|
||
|
+ gint i;
|
||
|
|
||
|
if (dispatch->backend->authentication_lock)
|
||
|
return FALSE;
|
||
|
@@ -717,6 +759,22 @@ request_password (gpointer data)
|
||
|
else
|
||
|
username = cupsUser ();
|
||
|
|
||
|
+ auth_info_required = g_new0 (gchar*, length + 1);
|
||
|
+ auth_info_required[0] = g_strdup ("hostname");
|
||
|
+ auth_info_required[1] = g_strdup ("username");
|
||
|
+ auth_info_required[2] = g_strdup ("password");
|
||
|
+
|
||
|
+ auth_info_default = g_new0 (gchar*, length + 1);
|
||
|
+ auth_info_default[0] = g_strdup (hostname);
|
||
|
+ auth_info_default[1] = g_strdup (username);
|
||
|
+
|
||
|
+ auth_info_display = g_new0 (gchar*, length + 1);
|
||
|
+ auth_info_display[1] = g_strdup (_("Username:"));
|
||
|
+ auth_info_display[2] = g_strdup (_("Password:"));
|
||
|
+
|
||
|
+ auth_info_visible = g_new0 (gboolean, length + 1);
|
||
|
+ auth_info_visible[1] = TRUE;
|
||
|
+
|
||
|
key = g_strconcat (username, "@", hostname, NULL);
|
||
|
password = g_hash_table_lookup (dispatch->backend->auth, key);
|
||
|
|
||
|
@@ -784,11 +842,22 @@ request_password (gpointer data)
|
||
|
g_free (printer_name);
|
||
|
|
||
|
g_signal_emit_by_name (dispatch->backend, "request-password",
|
||
|
- hostname, username, prompt);
|
||
|
+ auth_info_required, auth_info_default, auth_info_display, auth_info_visible, prompt);
|
||
|
|
||
|
g_free (prompt);
|
||
|
}
|
||
|
|
||
|
+ for (i = 0; i < length; i++)
|
||
|
+ {
|
||
|
+ g_free (auth_info_required[i]);
|
||
|
+ g_free (auth_info_default[i]);
|
||
|
+ g_free (auth_info_display[i]);
|
||
|
+ }
|
||
|
+
|
||
|
+ g_free (auth_info_required);
|
||
|
+ g_free (auth_info_default);
|
||
|
+ g_free (auth_info_display);
|
||
|
+ g_free (auth_info_visible);
|
||
|
g_free (key);
|
||
|
|
||
|
return FALSE;
|
||
|
@@ -828,6 +897,133 @@ cups_dispatch_add_poll (GSource *source)
|
||
|
}
|
||
|
|
||
|
static gboolean
|
||
|
+check_auth_info (gpointer user_data)
|
||
|
+{
|
||
|
+ GtkPrintCupsDispatchWatch *dispatch;
|
||
|
+ dispatch = (GtkPrintCupsDispatchWatch *) user_data;
|
||
|
+
|
||
|
+ if (!dispatch->request->need_auth_info)
|
||
|
+ {
|
||
|
+ if (dispatch->request->auth_info == NULL)
|
||
|
+ {
|
||
|
+ dispatch->callback (GTK_PRINT_BACKEND (dispatch->backend),
|
||
|
+ gtk_cups_request_get_result (dispatch->request),
|
||
|
+ dispatch->callback_data);
|
||
|
+ g_source_destroy ((GSource *) dispatch);
|
||
|
+ }
|
||
|
+ else
|
||
|
+ {
|
||
|
+ gint length;
|
||
|
+ gint i;
|
||
|
+
|
||
|
+ length = g_strv_length (dispatch->request->auth_info_required);
|
||
|
+
|
||
|
+ gtk_cups_request_ipp_add_strings (dispatch->request,
|
||
|
+ IPP_TAG_JOB,
|
||
|
+ IPP_TAG_TEXT,
|
||
|
+ "auth-info",
|
||
|
+ length,
|
||
|
+ NULL,
|
||
|
+ dispatch->request->auth_info);
|
||
|
+
|
||
|
+ g_source_attach ((GSource *) dispatch, NULL);
|
||
|
+ g_source_unref ((GSource *) dispatch);
|
||
|
+
|
||
|
+ for (i = 0; i < length; i++)
|
||
|
+ overwrite_and_free (dispatch->request->auth_info[i]);
|
||
|
+ g_free (dispatch->request->auth_info);
|
||
|
+ dispatch->request->auth_info = NULL;
|
||
|
+ }
|
||
|
+
|
||
|
+ return FALSE;
|
||
|
+ }
|
||
|
+
|
||
|
+ return TRUE;
|
||
|
+}
|
||
|
+
|
||
|
+static gboolean
|
||
|
+request_auth_info (gpointer user_data)
|
||
|
+{
|
||
|
+ GtkPrintCupsDispatchWatch *dispatch;
|
||
|
+ const char *job_title;
|
||
|
+ const char *printer_uri;
|
||
|
+ gchar *prompt = NULL;
|
||
|
+ char *printer_name = NULL;
|
||
|
+ gint length;
|
||
|
+ gint i;
|
||
|
+ gboolean *auth_info_visible = NULL;
|
||
|
+ gchar **auth_info_default = NULL;
|
||
|
+ gchar **auth_info_display = NULL;
|
||
|
+
|
||
|
+ dispatch = (GtkPrintCupsDispatchWatch *) user_data;
|
||
|
+
|
||
|
+ if (dispatch->backend->authentication_lock)
|
||
|
+ return FALSE;
|
||
|
+
|
||
|
+ job_title = gtk_cups_request_ipp_get_string (dispatch->request, IPP_TAG_NAME, "job-name");
|
||
|
+ printer_uri = gtk_cups_request_ipp_get_string (dispatch->request, IPP_TAG_URI, "printer-uri");
|
||
|
+ length = g_strv_length (dispatch->request->auth_info_required);
|
||
|
+
|
||
|
+ auth_info_visible = g_new0 (gboolean, length);
|
||
|
+ auth_info_default = g_new0 (gchar *, length + 1);
|
||
|
+ auth_info_display = g_new0 (gchar *, length + 1);
|
||
|
+
|
||
|
+ for (i = 0; i < length; i++)
|
||
|
+ {
|
||
|
+ if (g_strcmp0 (dispatch->request->auth_info_required[i], "domain") == 0)
|
||
|
+ {
|
||
|
+ auth_info_display[i] = g_strdup (_("Domain:"));
|
||
|
+ auth_info_default[i] = g_strdup ("WORKGROUP");
|
||
|
+ auth_info_visible[i] = TRUE;
|
||
|
+ }
|
||
|
+ else if (g_strcmp0 (dispatch->request->auth_info_required[i], "username") == 0)
|
||
|
+ {
|
||
|
+ auth_info_display[i] = g_strdup (_("Username:"));
|
||
|
+ if (dispatch->backend->username != NULL)
|
||
|
+ auth_info_default[i] = g_strdup (dispatch->backend->username);
|
||
|
+ else
|
||
|
+ auth_info_default[i] = g_strdup (cupsUser ());
|
||
|
+ auth_info_visible[i] = TRUE;
|
||
|
+ }
|
||
|
+ else if (g_strcmp0 (dispatch->request->auth_info_required[i], "password") == 0)
|
||
|
+ {
|
||
|
+ auth_info_display[i] = g_strdup (_("Password:"));
|
||
|
+ auth_info_visible[i] = FALSE;
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ if (printer_uri != NULL && strrchr (printer_uri, '/') != NULL)
|
||
|
+ printer_name = g_strdup (strrchr (printer_uri, '/') + 1);
|
||
|
+
|
||
|
+ dispatch->backend->authentication_lock = TRUE;
|
||
|
+
|
||
|
+ if (job_title != NULL && printer_name != NULL)
|
||
|
+ prompt = g_strdup_printf ( _("Authentication informations are required to print document '%s' on printer %s"), job_title, printer_name);
|
||
|
+
|
||
|
+ g_signal_emit_by_name (dispatch->backend, "request-password",
|
||
|
+ dispatch->request->auth_info_required,
|
||
|
+ auth_info_default,
|
||
|
+ auth_info_display,
|
||
|
+ auth_info_visible,
|
||
|
+ prompt);
|
||
|
+
|
||
|
+ for (i = 0; i < length; i++)
|
||
|
+ {
|
||
|
+ g_free (auth_info_default[i]);
|
||
|
+ g_free (auth_info_display[i]);
|
||
|
+ }
|
||
|
+
|
||
|
+ g_free (auth_info_default);
|
||
|
+ g_free (auth_info_display);
|
||
|
+ g_free (printer_name);
|
||
|
+ g_free (prompt);
|
||
|
+
|
||
|
+ g_idle_add (check_auth_info, user_data);
|
||
|
+
|
||
|
+ return FALSE;
|
||
|
+}
|
||
|
+
|
||
|
+static gboolean
|
||
|
cups_dispatch_watch_check (GSource *source)
|
||
|
{
|
||
|
GtkPrintCupsDispatchWatch *dispatch;
|
||
|
@@ -1008,13 +1204,24 @@ cups_request_execute (GtkPrintBackendCups *print_backend,
|
||
|
dispatch->request = request;
|
||
|
dispatch->backend = g_object_ref (print_backend);
|
||
|
dispatch->data_poll = NULL;
|
||
|
+ dispatch->callback = NULL;
|
||
|
+ dispatch->callback_data = NULL;
|
||
|
|
||
|
print_backend->requests = g_list_prepend (print_backend->requests, dispatch);
|
||
|
|
||
|
g_source_set_callback ((GSource *) dispatch, (GSourceFunc) callback, user_data, notify);
|
||
|
|
||
|
- g_source_attach ((GSource *) dispatch, NULL);
|
||
|
- g_source_unref ((GSource *) dispatch);
|
||
|
+ if (request->need_auth_info)
|
||
|
+ {
|
||
|
+ dispatch->callback = callback;
|
||
|
+ dispatch->callback_data = user_data;
|
||
|
+ request_auth_info (dispatch);
|
||
|
+ }
|
||
|
+ else
|
||
|
+ {
|
||
|
+ g_source_attach ((GSource *) dispatch, NULL);
|
||
|
+ g_source_unref ((GSource *) dispatch);
|
||
|
+ }
|
||
|
}
|
||
|
|
||
|
#if 0
|
||
|
@@ -1435,6 +1642,7 @@ cups_request_printer_list_cb (GtkPrintBackendCups *cups_backend,
|
||
|
gchar *default_cover_before = NULL;
|
||
|
gchar *default_cover_after = NULL;
|
||
|
gboolean remote_printer = FALSE;
|
||
|
+ gchar **auth_info_required = NULL;
|
||
|
|
||
|
/* Skip leading attributes until we hit a printer...
|
||
|
*/
|
||
|
@@ -1553,6 +1761,15 @@ cups_request_printer_list_cb (GtkPrintBackendCups *cups_backend,
|
||
|
else
|
||
|
remote_printer = FALSE;
|
||
|
}
|
||
|
+ else if (strcmp (attr->name, "auth-info-required") == 0)
|
||
|
+ {
|
||
|
+ if (strcmp (attr->values[0].string.text, "none") != 0)
|
||
|
+ {
|
||
|
+ auth_info_required = g_new0 (gchar *, attr->num_values + 1);
|
||
|
+ for (i = 0; i < attr->num_values; i++)
|
||
|
+ auth_info_required[i] = g_strdup (attr->values[i].string.text);
|
||
|
+ }
|
||
|
+ }
|
||
|
else
|
||
|
{
|
||
|
GTK_NOTE (PRINTING,
|
||
|
@@ -1674,6 +1891,9 @@ cups_request_printer_list_cb (GtkPrintBackendCups *cups_backend,
|
||
|
cups_printer->hostname = g_strdup (hostname);
|
||
|
cups_printer->port = port;
|
||
|
|
||
|
+ cups_printer->auth_info_required = g_strdupv (auth_info_required);
|
||
|
+ g_strfreev (auth_info_required);
|
||
|
+
|
||
|
printer = GTK_PRINTER (cups_printer);
|
||
|
|
||
|
if (cups_backend->default_printer != NULL &&
|
||
|
@@ -1866,7 +2086,8 @@ cups_request_printer_list (GtkPrintBackendCups *cups_backend)
|
||
|
"printer-is-accepting-jobs",
|
||
|
"job-sheets-supported",
|
||
|
"job-sheets-default",
|
||
|
- "printer-type"
|
||
|
+ "printer-type",
|
||
|
+ "auth-info-required"
|
||
|
};
|
||
|
|
||
|
if (cups_backend->list_printers_pending)
|
||
|
diff --git a/modules/printbackends/cups/gtkprintercups.c b/modules/printbackends/cups/gtkprintercups.c
|
||
|
index cd27b17..efdb0e5 100644
|
||
|
--- a/modules/printbackends/cups/gtkprintercups.c
|
||
|
+++ b/modules/printbackends/cups/gtkprintercups.c
|
||
|
@@ -77,6 +77,7 @@ gtk_printer_cups_init (GtkPrinterCups *printer)
|
||
|
printer->ppd_file = NULL;
|
||
|
printer->default_cover_before = NULL;
|
||
|
printer->default_cover_after = NULL;
|
||
|
+ printer->auth_info_required = NULL;
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
@@ -94,6 +95,7 @@ gtk_printer_cups_finalize (GObject *object)
|
||
|
g_free (printer->ppd_name);
|
||
|
g_free (printer->default_cover_before);
|
||
|
g_free (printer->default_cover_after);
|
||
|
+ g_strfreev (printer->auth_info_required);
|
||
|
|
||
|
if (printer->ppd_file)
|
||
|
ppdClose (printer->ppd_file);
|
||
|
diff --git a/modules/printbackends/cups/gtkprintercups.h b/modules/printbackends/cups/gtkprintercups.h
|
||
|
index cd2b318..7a869a0 100644
|
||
|
--- a/modules/printbackends/cups/gtkprintercups.h
|
||
|
+++ b/modules/printbackends/cups/gtkprintercups.h
|
||
|
@@ -47,6 +47,7 @@ struct _GtkPrinterCups
|
||
|
gchar *printer_uri;
|
||
|
gchar *hostname;
|
||
|
gint port;
|
||
|
+ gchar **auth_info_required;
|
||
|
|
||
|
ipp_pstate_t state;
|
||
|
gboolean reading_ppd;
|
||
|
--
|
||
|
1.6.2.5
|
||
|
|