• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* GIO - GLib Input, Output and Streaming Library
2  *
3  * Copyright (C) 2006-2007 Red Hat, Inc.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General
16  * Public License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18  * Boston, MA 02111-1307, USA.
19  *
20  * Author: Alexander Larsson <alexl@redhat.com>
21  */
22 
23 #include "config.h"
24 
25 #include <string.h>
26 
27 #include "gmountoperation.h"
28 #include "gioenumtypes.h"
29 #include "gio-marshal.h"
30 #include "glibintl.h"
31 
32 #include "gioalias.h"
33 
34 /**
35  * SECTION:gmountoperation
36  * @short_description: Authentication methods for mountable locations
37  * @include: gio/gio.h
38  *
39  * #GMountOperation provides a mechanism for authenticating mountable
40  * operations, such as loop mounting files, hard drive partitions or
41  * server locations.
42  *
43  * Mounting operations are handed a #GMountOperation that then can use
44  * if they require any privileges or authentication for their volumes
45  * to be mounted (e.g. a hard disk partition or an encrypted filesystem),
46  * or if they are implementing a remote server protocol which requires
47  * user credentials such as FTP or WebDAV.
48  *
49  * Users should instantiate a subclass of this that implements all
50  * the various callbacks to show the required dialogs, such as
51  * #GtkMountOperation.
52  **/
53 
54 G_DEFINE_TYPE (GMountOperation, g_mount_operation, G_TYPE_OBJECT);
55 
56 enum {
57   ASK_PASSWORD,
58   ASK_QUESTION,
59   REPLY,
60   ABORTED,
61   LAST_SIGNAL
62 };
63 
64 static guint signals[LAST_SIGNAL] = { 0 };
65 
66 struct _GMountOperationPrivate {
67   char *password;
68   char *user;
69   char *domain;
70   gboolean anonymous;
71   GPasswordSave password_save;
72   int choice;
73 };
74 
75 enum {
76   PROP_0,
77   PROP_USERNAME,
78   PROP_PASSWORD,
79   PROP_ANONYMOUS,
80   PROP_DOMAIN,
81   PROP_PASSWORD_SAVE,
82   PROP_CHOICE
83 };
84 
85 static void
g_mount_operation_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)86 g_mount_operation_set_property (GObject      *object,
87                                 guint         prop_id,
88                                 const GValue *value,
89                                 GParamSpec   *pspec)
90 {
91   GMountOperation *operation;
92 
93   operation = G_MOUNT_OPERATION (object);
94 
95   switch (prop_id)
96     {
97     case PROP_USERNAME:
98       g_mount_operation_set_username (operation,
99                                       g_value_get_string (value));
100       break;
101 
102     case PROP_PASSWORD:
103       g_mount_operation_set_password (operation,
104                                       g_value_get_string (value));
105       break;
106 
107     case PROP_ANONYMOUS:
108       g_mount_operation_set_anonymous (operation,
109                                        g_value_get_boolean (value));
110       break;
111 
112     case PROP_DOMAIN:
113       g_mount_operation_set_domain (operation,
114                                     g_value_get_string (value));
115       break;
116 
117     case PROP_PASSWORD_SAVE:
118       g_mount_operation_set_password_save (operation,
119                                            g_value_get_enum (value));
120       break;
121 
122     case PROP_CHOICE:
123       g_mount_operation_set_choice (operation,
124                                     g_value_get_int (value));
125       break;
126 
127     default:
128       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
129       break;
130     }
131 }
132 
133 
134 static void
g_mount_operation_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)135 g_mount_operation_get_property (GObject    *object,
136                                 guint       prop_id,
137                                 GValue     *value,
138                                 GParamSpec *pspec)
139 {
140   GMountOperation *operation;
141   GMountOperationPrivate *priv;
142 
143   operation = G_MOUNT_OPERATION (object);
144   priv = operation->priv;
145 
146   switch (prop_id)
147     {
148     case PROP_USERNAME:
149       g_value_set_string (value, priv->user);
150       break;
151 
152     case PROP_PASSWORD:
153       g_value_set_string (value, priv->password);
154       break;
155 
156     case PROP_ANONYMOUS:
157       g_value_set_boolean (value, priv->anonymous);
158       break;
159 
160     case PROP_DOMAIN:
161       g_value_set_string (value, priv->domain);
162       break;
163 
164     case PROP_PASSWORD_SAVE:
165       g_value_set_enum (value, priv->password_save);
166       break;
167 
168     case PROP_CHOICE:
169       g_value_set_int (value, priv->choice);
170       break;
171 
172     default:
173       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
174       break;
175     }
176 }
177 
178 
179 static void
g_mount_operation_finalize(GObject * object)180 g_mount_operation_finalize (GObject *object)
181 {
182   GMountOperation *operation;
183   GMountOperationPrivate *priv;
184 
185   operation = G_MOUNT_OPERATION (object);
186 
187   priv = operation->priv;
188 
189   g_free (priv->password);
190   g_free (priv->user);
191   g_free (priv->domain);
192 
193   G_OBJECT_CLASS (g_mount_operation_parent_class)->finalize (object);
194 }
195 
196 static gboolean
reply_non_handled_in_idle(gpointer data)197 reply_non_handled_in_idle (gpointer data)
198 {
199   GMountOperation *op = data;
200 
201   g_mount_operation_reply (op, G_MOUNT_OPERATION_UNHANDLED);
202   return FALSE;
203 }
204 
205 static void
ask_password(GMountOperation * op,const char * message,const char * default_user,const char * default_domain,GAskPasswordFlags flags)206 ask_password (GMountOperation *op,
207 	      const char      *message,
208 	      const char      *default_user,
209 	      const char      *default_domain,
210 	      GAskPasswordFlags flags)
211 {
212   g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
213 		   reply_non_handled_in_idle,
214 		   g_object_ref (op),
215 		   g_object_unref);
216 }
217 
218 static void
ask_question(GMountOperation * op,const char * message,const char * choices[])219 ask_question (GMountOperation *op,
220 	      const char      *message,
221 	      const char      *choices[])
222 {
223   g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
224 		   reply_non_handled_in_idle,
225 		   g_object_ref (op),
226 		   g_object_unref);
227 }
228 
229 static void
g_mount_operation_class_init(GMountOperationClass * klass)230 g_mount_operation_class_init (GMountOperationClass *klass)
231 {
232   GObjectClass *object_class;
233 
234   g_type_class_add_private (klass, sizeof (GMountOperationPrivate));
235 
236   object_class = G_OBJECT_CLASS (klass);
237   object_class->finalize = g_mount_operation_finalize;
238   object_class->get_property = g_mount_operation_get_property;
239   object_class->set_property = g_mount_operation_set_property;
240 
241   klass->ask_password = ask_password;
242   klass->ask_question = ask_question;
243 
244   /**
245    * GMountOperation::ask-password:
246    * @op: a #GMountOperation requesting a password.
247    * @message: string containing a message to display to the user.
248    * @default_user: string containing the default user name.
249    * @default_domain: string containing the default domain.
250    * @flags: a set of #GAskPasswordFlags.
251    *
252    * Emitted when a mount operation asks the user for a password.
253    *
254    * If the message contains a line break, the first line should be
255    * presented as a heading. For example, it may be used as the
256    * primary text in a #GtkMessageDialog.
257    */
258   signals[ASK_PASSWORD] =
259     g_signal_new (I_("ask-password"),
260 		  G_TYPE_FROM_CLASS (object_class),
261 		  G_SIGNAL_RUN_LAST,
262 		  G_STRUCT_OFFSET (GMountOperationClass, ask_password),
263 		  NULL, NULL,
264 		  _gio_marshal_VOID__STRING_STRING_STRING_FLAGS,
265 		  G_TYPE_NONE, 4,
266 		  G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_ASK_PASSWORD_FLAGS);
267 
268   /**
269    * GMountOperation::ask-question:
270    * @op: a #GMountOperation asking a question.
271    * @message: string containing a message to display to the user.
272    * @choices: an array of strings for each possible choice.
273    *
274    * Emitted when asking the user a question and gives a list of
275    * choices for the user to choose from.
276    *
277    * If the message contains a line break, the first line should be
278    * presented as a heading. For example, it may be used as the
279    * primary text in a #GtkMessageDialog.
280    */
281   signals[ASK_QUESTION] =
282     g_signal_new (I_("ask-question"),
283 		  G_TYPE_FROM_CLASS (object_class),
284 		  G_SIGNAL_RUN_LAST,
285 		  G_STRUCT_OFFSET (GMountOperationClass, ask_question),
286 		  NULL, NULL,
287 		  _gio_marshal_VOID__STRING_BOXED,
288 		  G_TYPE_NONE, 2,
289 		  G_TYPE_STRING, G_TYPE_STRV);
290 
291   /**
292    * GMountOperation::reply:
293    * @op: a #GMountOperation.
294    * @result: a #GMountOperationResult indicating how the request was handled
295    *
296    * Emitted when the user has replied to the mount operation.
297    */
298   signals[REPLY] =
299     g_signal_new (I_("reply"),
300 		  G_TYPE_FROM_CLASS (object_class),
301 		  G_SIGNAL_RUN_LAST,
302 		  G_STRUCT_OFFSET (GMountOperationClass, reply),
303 		  NULL, NULL,
304 		  g_cclosure_marshal_VOID__ENUM,
305 		  G_TYPE_NONE, 1,
306 		  G_TYPE_MOUNT_OPERATION_RESULT);
307 
308   /**
309    * GMountOperation::aborted:
310    *
311    * Emitted by the backend when e.g. a device becomes unavailable
312    * while a mount operation is in progress.
313    *
314    * Implementations of GMountOperation should handle this signal
315    * by dismissing open password dialogs.
316    *
317    * Since: 2.20
318    */
319   signals[ABORTED] =
320     g_signal_new (I_("aborted"),
321 		  G_TYPE_FROM_CLASS (object_class),
322 		  G_SIGNAL_RUN_LAST,
323 		  G_STRUCT_OFFSET (GMountOperationClass, aborted),
324 		  NULL, NULL,
325 		  g_cclosure_marshal_VOID__VOID,
326 		  G_TYPE_NONE, 0);
327 
328   /**
329    * GMountOperation:username:
330    *
331    * The user name that is used for authentication when carrying out
332    * the mount operation.
333    */
334   g_object_class_install_property (object_class,
335                                    PROP_USERNAME,
336                                    g_param_spec_string ("username",
337                                                         P_("Username"),
338                                                         P_("The user name"),
339                                                         NULL,
340                                                         G_PARAM_READWRITE|
341                                                         G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
342 
343   /**
344    * GMountOperation:password:
345    *
346    * The password that is used for authentication when carrying out
347    * the mount operation.
348    */
349   g_object_class_install_property (object_class,
350                                    PROP_PASSWORD,
351                                    g_param_spec_string ("password",
352                                                         P_("Password"),
353                                                         P_("The password"),
354                                                         NULL,
355                                                         G_PARAM_READWRITE|
356                                                         G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
357 
358   /**
359    * GMountOperation:anonymous:
360    *
361    * Whether to use an anonymous user when authenticating.
362    */
363   g_object_class_install_property (object_class,
364                                    PROP_ANONYMOUS,
365                                    g_param_spec_boolean ("anonymous",
366                                                          P_("Anonymous"),
367                                                          P_("Whether to use an anonymous user"),
368                                                          FALSE,
369                                                          G_PARAM_READWRITE|
370                                                          G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
371 
372   /**
373    * GMountOperation:domain:
374    *
375    * The domain to use for the mount operation.
376    */
377   g_object_class_install_property (object_class,
378                                    PROP_DOMAIN,
379                                    g_param_spec_string ("domain",
380                                                         P_("Domain"),
381                                                         P_("The domain of the mount operation"),
382                                                         NULL,
383                                                         G_PARAM_READWRITE|
384                                                         G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
385 
386   /**
387    * GMountOperation:password-save:
388    *
389    * Determines if and how the password information should be saved.
390    */
391   g_object_class_install_property (object_class,
392                                    PROP_PASSWORD_SAVE,
393                                    g_param_spec_enum ("password-save",
394                                                       P_("Password save"),
395                                                       P_("How passwords should be saved"),
396                                                       G_TYPE_PASSWORD_SAVE,
397                                                       G_PASSWORD_SAVE_NEVER,
398                                                       G_PARAM_READWRITE|
399                                                       G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
400 
401   /**
402    * GMountOperation:choice:
403    *
404    * The index of the user's choice when a question is asked during the
405    * mount operation. See the #GMountOperation::ask-question signal.
406    */
407   g_object_class_install_property (object_class,
408                                    PROP_CHOICE,
409                                    g_param_spec_int ("choice",
410                                                      P_("Choice"),
411                                                      P_("The users choice"),
412                                                      0, G_MAXINT, 0,
413                                                      G_PARAM_READWRITE|
414                                                      G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
415 }
416 
417 static void
g_mount_operation_init(GMountOperation * operation)418 g_mount_operation_init (GMountOperation *operation)
419 {
420   operation->priv = G_TYPE_INSTANCE_GET_PRIVATE (operation,
421 						 G_TYPE_MOUNT_OPERATION,
422 						 GMountOperationPrivate);
423 }
424 
425 /**
426  * g_mount_operation_new:
427  *
428  * Creates a new mount operation.
429  *
430  * Returns: a #GMountOperation.
431  **/
432 GMountOperation *
g_mount_operation_new(void)433 g_mount_operation_new (void)
434 {
435   return g_object_new (G_TYPE_MOUNT_OPERATION, NULL);
436 }
437 
438 /**
439  * g_mount_operation_get_username
440  * @op: a #GMountOperation.
441  *
442  * Get the user name from the mount operation.
443  *
444  * Returns: a string containing the user name.
445  **/
446 const char *
g_mount_operation_get_username(GMountOperation * op)447 g_mount_operation_get_username (GMountOperation *op)
448 {
449   g_return_val_if_fail (G_IS_MOUNT_OPERATION (op), NULL);
450   return op->priv->user;
451 }
452 
453 /**
454  * g_mount_operation_set_username:
455  * @op: a #GMountOperation.
456  * @username: input username.
457  *
458  * Sets the user name within @op to @username.
459  **/
460 void
g_mount_operation_set_username(GMountOperation * op,const char * username)461 g_mount_operation_set_username (GMountOperation *op,
462 				const char      *username)
463 {
464   g_return_if_fail (G_IS_MOUNT_OPERATION (op));
465   g_free (op->priv->user);
466   op->priv->user = g_strdup (username);
467   g_object_notify (G_OBJECT (op), "username");
468 }
469 
470 /**
471  * g_mount_operation_get_password:
472  * @op: a #GMountOperation.
473  *
474  * Gets a password from the mount operation.
475  *
476  * Returns: a string containing the password within @op.
477  **/
478 const char *
g_mount_operation_get_password(GMountOperation * op)479 g_mount_operation_get_password (GMountOperation *op)
480 {
481   g_return_val_if_fail (G_IS_MOUNT_OPERATION (op), NULL);
482   return op->priv->password;
483 }
484 
485 /**
486  * g_mount_operation_set_password:
487  * @op: a #GMountOperation.
488  * @password: password to set.
489  *
490  * Sets the mount operation's password to @password.
491  *
492  **/
493 void
g_mount_operation_set_password(GMountOperation * op,const char * password)494 g_mount_operation_set_password (GMountOperation *op,
495 				const char      *password)
496 {
497   g_return_if_fail (G_IS_MOUNT_OPERATION (op));
498   g_free (op->priv->password);
499   op->priv->password = g_strdup (password);
500   g_object_notify (G_OBJECT (op), "password");
501 }
502 
503 /**
504  * g_mount_operation_get_anonymous:
505  * @op: a #GMountOperation.
506  *
507  * Check to see whether the mount operation is being used
508  * for an anonymous user.
509  *
510  * Returns: %TRUE if mount operation is anonymous.
511  **/
512 gboolean
g_mount_operation_get_anonymous(GMountOperation * op)513 g_mount_operation_get_anonymous (GMountOperation *op)
514 {
515   g_return_val_if_fail (G_IS_MOUNT_OPERATION (op), FALSE);
516   return op->priv->anonymous;
517 }
518 
519 /**
520  * g_mount_operation_set_anonymous:
521  * @op: a #GMountOperation.
522  * @anonymous: boolean value.
523  *
524  * Sets the mount operation to use an anonymous user if @anonymous is %TRUE.
525  **/
526 void
g_mount_operation_set_anonymous(GMountOperation * op,gboolean anonymous)527 g_mount_operation_set_anonymous (GMountOperation *op,
528 				 gboolean         anonymous)
529 {
530   GMountOperationPrivate *priv;
531   g_return_if_fail (G_IS_MOUNT_OPERATION (op));
532   priv = op->priv;
533 
534   if (priv->anonymous != anonymous)
535     {
536       priv->anonymous = anonymous;
537       g_object_notify (G_OBJECT (op), "anonymous");
538     }
539 }
540 
541 /**
542  * g_mount_operation_get_domain:
543  * @op: a #GMountOperation.
544  *
545  * Gets the domain of the mount operation.
546  *
547  * Returns: a string set to the domain.
548  **/
549 const char *
g_mount_operation_get_domain(GMountOperation * op)550 g_mount_operation_get_domain (GMountOperation *op)
551 {
552   g_return_val_if_fail (G_IS_MOUNT_OPERATION (op), NULL);
553   return op->priv->domain;
554 }
555 
556 /**
557  * g_mount_operation_set_domain:
558  * @op: a #GMountOperation.
559  * @domain: the domain to set.
560  *
561  * Sets the mount operation's domain.
562  **/
563 void
g_mount_operation_set_domain(GMountOperation * op,const char * domain)564 g_mount_operation_set_domain (GMountOperation *op,
565 			      const char      *domain)
566 {
567   g_return_if_fail (G_IS_MOUNT_OPERATION (op));
568   g_free (op->priv->domain);
569   op->priv->domain = g_strdup (domain);
570   g_object_notify (G_OBJECT (op), "domain");
571 }
572 
573 /**
574  * g_mount_operation_get_password_save:
575  * @op: a #GMountOperation.
576  *
577  * Gets the state of saving passwords for the mount operation.
578  *
579  * Returns: a #GPasswordSave flag.
580  **/
581 
582 GPasswordSave
g_mount_operation_get_password_save(GMountOperation * op)583 g_mount_operation_get_password_save (GMountOperation *op)
584 {
585   g_return_val_if_fail (G_IS_MOUNT_OPERATION (op), G_PASSWORD_SAVE_NEVER);
586   return op->priv->password_save;
587 }
588 
589 /**
590  * g_mount_operation_set_password_save:
591  * @op: a #GMountOperation.
592  * @save: a set of #GPasswordSave flags.
593  *
594  * Sets the state of saving passwords for the mount operation.
595  *
596  **/
597 void
g_mount_operation_set_password_save(GMountOperation * op,GPasswordSave save)598 g_mount_operation_set_password_save (GMountOperation *op,
599 				     GPasswordSave    save)
600 {
601   GMountOperationPrivate *priv;
602   g_return_if_fail (G_IS_MOUNT_OPERATION (op));
603   priv = op->priv;
604 
605   if (priv->password_save != save)
606     {
607       priv->password_save = save;
608       g_object_notify (G_OBJECT (op), "password-save");
609     }
610 }
611 
612 /**
613  * g_mount_operation_get_choice:
614  * @op: a #GMountOperation.
615  *
616  * Gets a choice from the mount operation.
617  *
618  * Returns: an integer containing an index of the user's choice from
619  * the choice's list, or %0.
620  **/
621 int
g_mount_operation_get_choice(GMountOperation * op)622 g_mount_operation_get_choice (GMountOperation *op)
623 {
624   g_return_val_if_fail (G_IS_MOUNT_OPERATION (op), 0);
625   return op->priv->choice;
626 }
627 
628 /**
629  * g_mount_operation_set_choice:
630  * @op: a #GMountOperation.
631  * @choice: an integer.
632  *
633  * Sets a default choice for the mount operation.
634  **/
635 void
g_mount_operation_set_choice(GMountOperation * op,int choice)636 g_mount_operation_set_choice (GMountOperation *op,
637 			      int              choice)
638 {
639   GMountOperationPrivate *priv;
640   g_return_if_fail (G_IS_MOUNT_OPERATION (op));
641   priv = op->priv;
642   if (priv->choice != choice)
643     {
644       priv->choice = choice;
645       g_object_notify (G_OBJECT (op), "choice");
646     }
647 }
648 
649 /**
650  * g_mount_operation_reply:
651  * @op: a #GMountOperation
652  * @result: a #GMountOperationResult
653  *
654  * Emits the #GMountOperation::reply signal.
655  **/
656 void
g_mount_operation_reply(GMountOperation * op,GMountOperationResult result)657 g_mount_operation_reply (GMountOperation *op,
658 			 GMountOperationResult result)
659 {
660   g_return_if_fail (G_IS_MOUNT_OPERATION (op));
661   g_signal_emit (op, signals[REPLY], 0, result);
662 }
663 
664 #define __G_MOUNT_OPERATION_C__
665 #include "gioaliasdef.c"
666