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.1 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, see <http://www.gnu.org/licenses/>. |
17 | * |
18 | * Author: Alexander Larsson <alexl@redhat.com> |
19 | */ |
20 | |
21 | #include "config.h" |
22 | |
23 | #include <string.h> |
24 | |
25 | #include "gmountoperation.h" |
26 | #include "gioenumtypes.h" |
27 | #include "glibintl.h" |
28 | #include "gmarshal-internal.h" |
29 | |
30 | |
31 | /** |
32 | * SECTION:gmountoperation |
33 | * @short_description: Object used for authentication and user interaction |
34 | * @include: gio/gio.h |
35 | * |
36 | * #GMountOperation provides a mechanism for interacting with the user. |
37 | * It can be used for authenticating mountable operations, such as loop |
38 | * mounting files, hard drive partitions or server locations. It can |
39 | * also be used to ask the user questions or show a list of applications |
40 | * preventing unmount or eject operations from completing. |
41 | * |
42 | * Note that #GMountOperation is used for more than just #GMount |
43 | * objects – for example it is also used in g_drive_start() and |
44 | * g_drive_stop(). |
45 | * |
46 | * Users should instantiate a subclass of this that implements all the |
47 | * various callbacks to show the required dialogs, such as |
48 | * #GtkMountOperation. If no user interaction is desired (for example |
49 | * when automounting filesystems at login time), usually %NULL can be |
50 | * passed, see each method taking a #GMountOperation for details. |
51 | * |
52 | * The term ‘TCRYPT’ is used to mean ‘compatible with TrueCrypt and VeraCrypt’. |
53 | * [TrueCrypt](https://en.wikipedia.org/wiki/TrueCrypt) is a discontinued system for |
54 | * encrypting file containers, partitions or whole disks, typically used with Windows. |
55 | * [VeraCrypt](https://www.veracrypt.fr/) is a maintained fork of TrueCrypt with various |
56 | * improvements and auditing fixes. |
57 | */ |
58 | |
59 | enum { |
60 | ASK_PASSWORD, |
61 | ASK_QUESTION, |
62 | REPLY, |
63 | ABORTED, |
64 | SHOW_PROCESSES, |
65 | SHOW_UNMOUNT_PROGRESS, |
66 | LAST_SIGNAL |
67 | }; |
68 | |
69 | static guint signals[LAST_SIGNAL] = { 0 }; |
70 | |
71 | struct _GMountOperationPrivate { |
72 | char *password; |
73 | char *user; |
74 | char *domain; |
75 | gboolean anonymous; |
76 | GPasswordSave password_save; |
77 | int choice; |
78 | gboolean hidden_volume; |
79 | gboolean system_volume; |
80 | guint pim; |
81 | }; |
82 | |
83 | enum { |
84 | PROP_0, |
85 | PROP_USERNAME, |
86 | PROP_PASSWORD, |
87 | PROP_ANONYMOUS, |
88 | PROP_DOMAIN, |
89 | PROP_PASSWORD_SAVE, |
90 | PROP_CHOICE, |
91 | PROP_IS_TCRYPT_HIDDEN_VOLUME, |
92 | PROP_IS_TCRYPT_SYSTEM_VOLUME, |
93 | PROP_PIM |
94 | }; |
95 | |
96 | G_DEFINE_TYPE_WITH_PRIVATE (GMountOperation, g_mount_operation, G_TYPE_OBJECT) |
97 | |
98 | static void |
99 | g_mount_operation_set_property (GObject *object, |
100 | guint prop_id, |
101 | const GValue *value, |
102 | GParamSpec *pspec) |
103 | { |
104 | GMountOperation *operation; |
105 | |
106 | operation = G_MOUNT_OPERATION (object); |
107 | |
108 | switch (prop_id) |
109 | { |
110 | case PROP_USERNAME: |
111 | g_mount_operation_set_username (op: operation, |
112 | username: g_value_get_string (value)); |
113 | break; |
114 | |
115 | case PROP_PASSWORD: |
116 | g_mount_operation_set_password (op: operation, |
117 | password: g_value_get_string (value)); |
118 | break; |
119 | |
120 | case PROP_ANONYMOUS: |
121 | g_mount_operation_set_anonymous (op: operation, |
122 | anonymous: g_value_get_boolean (value)); |
123 | break; |
124 | |
125 | case PROP_DOMAIN: |
126 | g_mount_operation_set_domain (op: operation, |
127 | domain: g_value_get_string (value)); |
128 | break; |
129 | |
130 | case PROP_PASSWORD_SAVE: |
131 | g_mount_operation_set_password_save (op: operation, |
132 | save: g_value_get_enum (value)); |
133 | break; |
134 | |
135 | case PROP_CHOICE: |
136 | g_mount_operation_set_choice (op: operation, |
137 | choice: g_value_get_int (value)); |
138 | break; |
139 | |
140 | case PROP_IS_TCRYPT_HIDDEN_VOLUME: |
141 | g_mount_operation_set_is_tcrypt_hidden_volume (op: operation, |
142 | hidden_volume: g_value_get_boolean (value)); |
143 | break; |
144 | |
145 | case PROP_IS_TCRYPT_SYSTEM_VOLUME: |
146 | g_mount_operation_set_is_tcrypt_system_volume (op: operation, |
147 | system_volume: g_value_get_boolean (value)); |
148 | break; |
149 | |
150 | case PROP_PIM: |
151 | g_mount_operation_set_pim (op: operation, |
152 | pim: g_value_get_uint (value)); |
153 | break; |
154 | |
155 | default: |
156 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
157 | break; |
158 | } |
159 | } |
160 | |
161 | |
162 | static void |
163 | g_mount_operation_get_property (GObject *object, |
164 | guint prop_id, |
165 | GValue *value, |
166 | GParamSpec *pspec) |
167 | { |
168 | GMountOperation *operation; |
169 | GMountOperationPrivate *priv; |
170 | |
171 | operation = G_MOUNT_OPERATION (object); |
172 | priv = operation->priv; |
173 | |
174 | switch (prop_id) |
175 | { |
176 | case PROP_USERNAME: |
177 | g_value_set_string (value, v_string: priv->user); |
178 | break; |
179 | |
180 | case PROP_PASSWORD: |
181 | g_value_set_string (value, v_string: priv->password); |
182 | break; |
183 | |
184 | case PROP_ANONYMOUS: |
185 | g_value_set_boolean (value, v_boolean: priv->anonymous); |
186 | break; |
187 | |
188 | case PROP_DOMAIN: |
189 | g_value_set_string (value, v_string: priv->domain); |
190 | break; |
191 | |
192 | case PROP_PASSWORD_SAVE: |
193 | g_value_set_enum (value, v_enum: priv->password_save); |
194 | break; |
195 | |
196 | case PROP_CHOICE: |
197 | g_value_set_int (value, v_int: priv->choice); |
198 | break; |
199 | |
200 | case PROP_IS_TCRYPT_HIDDEN_VOLUME: |
201 | g_value_set_boolean (value, v_boolean: priv->hidden_volume); |
202 | break; |
203 | |
204 | case PROP_IS_TCRYPT_SYSTEM_VOLUME: |
205 | g_value_set_boolean (value, v_boolean: priv->system_volume); |
206 | break; |
207 | |
208 | case PROP_PIM: |
209 | g_value_set_uint (value, v_uint: priv->pim); |
210 | break; |
211 | |
212 | default: |
213 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
214 | break; |
215 | } |
216 | } |
217 | |
218 | |
219 | static void |
220 | g_mount_operation_finalize (GObject *object) |
221 | { |
222 | GMountOperation *operation; |
223 | GMountOperationPrivate *priv; |
224 | |
225 | operation = G_MOUNT_OPERATION (object); |
226 | |
227 | priv = operation->priv; |
228 | |
229 | g_free (mem: priv->password); |
230 | g_free (mem: priv->user); |
231 | g_free (mem: priv->domain); |
232 | |
233 | G_OBJECT_CLASS (g_mount_operation_parent_class)->finalize (object); |
234 | } |
235 | |
236 | static gboolean |
237 | reply_non_handled_in_idle (gpointer data) |
238 | { |
239 | GMountOperation *op = data; |
240 | |
241 | g_mount_operation_reply (op, result: G_MOUNT_OPERATION_UNHANDLED); |
242 | return G_SOURCE_REMOVE; |
243 | } |
244 | |
245 | static void |
246 | ask_password (GMountOperation *op, |
247 | const char *message, |
248 | const char *default_user, |
249 | const char *default_domain, |
250 | GAskPasswordFlags flags) |
251 | { |
252 | g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, |
253 | function: reply_non_handled_in_idle, |
254 | g_object_ref (op), |
255 | notify: g_object_unref); |
256 | } |
257 | |
258 | static void |
259 | ask_question (GMountOperation *op, |
260 | const char *message, |
261 | const char *choices[]) |
262 | { |
263 | g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, |
264 | function: reply_non_handled_in_idle, |
265 | g_object_ref (op), |
266 | notify: g_object_unref); |
267 | } |
268 | |
269 | static void |
270 | show_processes (GMountOperation *op, |
271 | const gchar *message, |
272 | GArray *processes, |
273 | const gchar *choices[]) |
274 | { |
275 | g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, |
276 | function: reply_non_handled_in_idle, |
277 | g_object_ref (op), |
278 | notify: g_object_unref); |
279 | } |
280 | |
281 | static void |
282 | show_unmount_progress (GMountOperation *op, |
283 | const gchar *message, |
284 | gint64 time_left, |
285 | gint64 bytes_left) |
286 | { |
287 | /* nothing to do */ |
288 | } |
289 | |
290 | static void |
291 | g_mount_operation_class_init (GMountOperationClass *klass) |
292 | { |
293 | GObjectClass *object_class; |
294 | |
295 | object_class = G_OBJECT_CLASS (klass); |
296 | object_class->finalize = g_mount_operation_finalize; |
297 | object_class->get_property = g_mount_operation_get_property; |
298 | object_class->set_property = g_mount_operation_set_property; |
299 | |
300 | klass->ask_password = ask_password; |
301 | klass->ask_question = ask_question; |
302 | klass->show_processes = show_processes; |
303 | klass->show_unmount_progress = show_unmount_progress; |
304 | |
305 | /** |
306 | * GMountOperation::ask-password: |
307 | * @op: a #GMountOperation requesting a password. |
308 | * @message: string containing a message to display to the user. |
309 | * @default_user: string containing the default user name. |
310 | * @default_domain: string containing the default domain. |
311 | * @flags: a set of #GAskPasswordFlags. |
312 | * |
313 | * Emitted when a mount operation asks the user for a password. |
314 | * |
315 | * If the message contains a line break, the first line should be |
316 | * presented as a heading. For example, it may be used as the |
317 | * primary text in a #GtkMessageDialog. |
318 | */ |
319 | signals[ASK_PASSWORD] = |
320 | g_signal_new (I_("ask-password" ), |
321 | G_TYPE_FROM_CLASS (object_class), |
322 | signal_flags: G_SIGNAL_RUN_LAST, |
323 | G_STRUCT_OFFSET (GMountOperationClass, ask_password), |
324 | NULL, NULL, |
325 | c_marshaller: _g_cclosure_marshal_VOID__STRING_STRING_STRING_FLAGS, |
326 | G_TYPE_NONE, n_params: 4, |
327 | G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_ASK_PASSWORD_FLAGS); |
328 | g_signal_set_va_marshaller (signal_id: signals[ASK_PASSWORD], |
329 | G_TYPE_FROM_CLASS (object_class), |
330 | va_marshaller: _g_cclosure_marshal_VOID__STRING_STRING_STRING_FLAGSv); |
331 | |
332 | /** |
333 | * GMountOperation::ask-question: |
334 | * @op: a #GMountOperation asking a question. |
335 | * @message: string containing a message to display to the user. |
336 | * @choices: an array of strings for each possible choice. |
337 | * |
338 | * Emitted when asking the user a question and gives a list of |
339 | * choices for the user to choose from. |
340 | * |
341 | * If the message contains a line break, the first line should be |
342 | * presented as a heading. For example, it may be used as the |
343 | * primary text in a #GtkMessageDialog. |
344 | */ |
345 | signals[ASK_QUESTION] = |
346 | g_signal_new (I_("ask-question" ), |
347 | G_TYPE_FROM_CLASS (object_class), |
348 | signal_flags: G_SIGNAL_RUN_LAST, |
349 | G_STRUCT_OFFSET (GMountOperationClass, ask_question), |
350 | NULL, NULL, |
351 | c_marshaller: _g_cclosure_marshal_VOID__STRING_BOXED, |
352 | G_TYPE_NONE, n_params: 2, |
353 | G_TYPE_STRING, G_TYPE_STRV); |
354 | g_signal_set_va_marshaller (signal_id: signals[ASK_QUESTION], |
355 | G_TYPE_FROM_CLASS (object_class), |
356 | va_marshaller: _g_cclosure_marshal_VOID__STRING_BOXEDv); |
357 | |
358 | /** |
359 | * GMountOperation::reply: |
360 | * @op: a #GMountOperation. |
361 | * @result: a #GMountOperationResult indicating how the request was handled |
362 | * |
363 | * Emitted when the user has replied to the mount operation. |
364 | */ |
365 | signals[REPLY] = |
366 | g_signal_new (I_("reply" ), |
367 | G_TYPE_FROM_CLASS (object_class), |
368 | signal_flags: G_SIGNAL_RUN_LAST, |
369 | G_STRUCT_OFFSET (GMountOperationClass, reply), |
370 | NULL, NULL, |
371 | NULL, |
372 | G_TYPE_NONE, n_params: 1, |
373 | G_TYPE_MOUNT_OPERATION_RESULT); |
374 | |
375 | /** |
376 | * GMountOperation::aborted: |
377 | * |
378 | * Emitted by the backend when e.g. a device becomes unavailable |
379 | * while a mount operation is in progress. |
380 | * |
381 | * Implementations of GMountOperation should handle this signal |
382 | * by dismissing open password dialogs. |
383 | * |
384 | * Since: 2.20 |
385 | */ |
386 | signals[ABORTED] = |
387 | g_signal_new (I_("aborted" ), |
388 | G_TYPE_FROM_CLASS (object_class), |
389 | signal_flags: G_SIGNAL_RUN_LAST, |
390 | G_STRUCT_OFFSET (GMountOperationClass, aborted), |
391 | NULL, NULL, |
392 | NULL, |
393 | G_TYPE_NONE, n_params: 0); |
394 | |
395 | /** |
396 | * GMountOperation::show-processes: |
397 | * @op: a #GMountOperation. |
398 | * @message: string containing a message to display to the user. |
399 | * @processes: (element-type GPid): an array of #GPid for processes |
400 | * blocking the operation. |
401 | * @choices: an array of strings for each possible choice. |
402 | * |
403 | * Emitted when one or more processes are blocking an operation |
404 | * e.g. unmounting/ejecting a #GMount or stopping a #GDrive. |
405 | * |
406 | * Note that this signal may be emitted several times to update the |
407 | * list of blocking processes as processes close files. The |
408 | * application should only respond with g_mount_operation_reply() to |
409 | * the latest signal (setting #GMountOperation:choice to the choice |
410 | * the user made). |
411 | * |
412 | * If the message contains a line break, the first line should be |
413 | * presented as a heading. For example, it may be used as the |
414 | * primary text in a #GtkMessageDialog. |
415 | * |
416 | * Since: 2.22 |
417 | */ |
418 | signals[SHOW_PROCESSES] = |
419 | g_signal_new (I_("show-processes" ), |
420 | G_TYPE_FROM_CLASS (object_class), |
421 | signal_flags: G_SIGNAL_RUN_LAST, |
422 | G_STRUCT_OFFSET (GMountOperationClass, show_processes), |
423 | NULL, NULL, |
424 | c_marshaller: _g_cclosure_marshal_VOID__STRING_BOXED_BOXED, |
425 | G_TYPE_NONE, n_params: 3, |
426 | G_TYPE_STRING, G_TYPE_ARRAY, G_TYPE_STRV); |
427 | g_signal_set_va_marshaller (signal_id: signals[SHOW_PROCESSES], |
428 | G_TYPE_FROM_CLASS (object_class), |
429 | va_marshaller: _g_cclosure_marshal_VOID__STRING_BOXED_BOXEDv); |
430 | |
431 | /** |
432 | * GMountOperation::show-unmount-progress: |
433 | * @op: a #GMountOperation: |
434 | * @message: string containing a message to display to the user |
435 | * @time_left: the estimated time left before the operation completes, |
436 | * in microseconds, or -1 |
437 | * @bytes_left: the amount of bytes to be written before the operation |
438 | * completes (or -1 if such amount is not known), or zero if the operation |
439 | * is completed |
440 | * |
441 | * Emitted when an unmount operation has been busy for more than some time |
442 | * (typically 1.5 seconds). |
443 | * |
444 | * When unmounting or ejecting a volume, the kernel might need to flush |
445 | * pending data in its buffers to the volume stable storage, and this operation |
446 | * can take a considerable amount of time. This signal may be emitted several |
447 | * times as long as the unmount operation is outstanding, and then one |
448 | * last time when the operation is completed, with @bytes_left set to zero. |
449 | * |
450 | * Implementations of GMountOperation should handle this signal by |
451 | * showing an UI notification, and then dismiss it, or show another notification |
452 | * of completion, when @bytes_left reaches zero. |
453 | * |
454 | * If the message contains a line break, the first line should be |
455 | * presented as a heading. For example, it may be used as the |
456 | * primary text in a #GtkMessageDialog. |
457 | * |
458 | * Since: 2.34 |
459 | */ |
460 | signals[SHOW_UNMOUNT_PROGRESS] = |
461 | g_signal_new (I_("show-unmount-progress" ), |
462 | G_TYPE_FROM_CLASS (object_class), |
463 | signal_flags: G_SIGNAL_RUN_LAST, |
464 | G_STRUCT_OFFSET (GMountOperationClass, show_unmount_progress), |
465 | NULL, NULL, |
466 | c_marshaller: _g_cclosure_marshal_VOID__STRING_INT64_INT64, |
467 | G_TYPE_NONE, n_params: 3, |
468 | G_TYPE_STRING, G_TYPE_INT64, G_TYPE_INT64); |
469 | g_signal_set_va_marshaller (signal_id: signals[SHOW_UNMOUNT_PROGRESS], |
470 | G_TYPE_FROM_CLASS (object_class), |
471 | va_marshaller: _g_cclosure_marshal_VOID__STRING_INT64_INT64v); |
472 | |
473 | /** |
474 | * GMountOperation:username: |
475 | * |
476 | * The user name that is used for authentication when carrying out |
477 | * the mount operation. |
478 | */ |
479 | g_object_class_install_property (oclass: object_class, |
480 | property_id: PROP_USERNAME, |
481 | pspec: g_param_spec_string (name: "username" , |
482 | P_("Username" ), |
483 | P_("The user name" ), |
484 | NULL, |
485 | flags: G_PARAM_READWRITE| |
486 | G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB)); |
487 | |
488 | /** |
489 | * GMountOperation:password: |
490 | * |
491 | * The password that is used for authentication when carrying out |
492 | * the mount operation. |
493 | */ |
494 | g_object_class_install_property (oclass: object_class, |
495 | property_id: PROP_PASSWORD, |
496 | pspec: g_param_spec_string (name: "password" , |
497 | P_("Password" ), |
498 | P_("The password" ), |
499 | NULL, |
500 | flags: G_PARAM_READWRITE| |
501 | G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB)); |
502 | |
503 | /** |
504 | * GMountOperation:anonymous: |
505 | * |
506 | * Whether to use an anonymous user when authenticating. |
507 | */ |
508 | g_object_class_install_property (oclass: object_class, |
509 | property_id: PROP_ANONYMOUS, |
510 | pspec: g_param_spec_boolean (name: "anonymous" , |
511 | P_("Anonymous" ), |
512 | P_("Whether to use an anonymous user" ), |
513 | FALSE, |
514 | flags: G_PARAM_READWRITE| |
515 | G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB)); |
516 | |
517 | /** |
518 | * GMountOperation:domain: |
519 | * |
520 | * The domain to use for the mount operation. |
521 | */ |
522 | g_object_class_install_property (oclass: object_class, |
523 | property_id: PROP_DOMAIN, |
524 | pspec: g_param_spec_string (name: "domain" , |
525 | P_("Domain" ), |
526 | P_("The domain of the mount operation" ), |
527 | NULL, |
528 | flags: G_PARAM_READWRITE| |
529 | G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB)); |
530 | |
531 | /** |
532 | * GMountOperation:password-save: |
533 | * |
534 | * Determines if and how the password information should be saved. |
535 | */ |
536 | g_object_class_install_property (oclass: object_class, |
537 | property_id: PROP_PASSWORD_SAVE, |
538 | pspec: g_param_spec_enum (name: "password-save" , |
539 | P_("Password save" ), |
540 | P_("How passwords should be saved" ), |
541 | enum_type: G_TYPE_PASSWORD_SAVE, |
542 | default_value: G_PASSWORD_SAVE_NEVER, |
543 | flags: G_PARAM_READWRITE| |
544 | G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB)); |
545 | |
546 | /** |
547 | * GMountOperation:choice: |
548 | * |
549 | * The index of the user's choice when a question is asked during the |
550 | * mount operation. See the #GMountOperation::ask-question signal. |
551 | */ |
552 | g_object_class_install_property (oclass: object_class, |
553 | property_id: PROP_CHOICE, |
554 | pspec: g_param_spec_int (name: "choice" , |
555 | P_("Choice" ), |
556 | P_("The users choice" ), |
557 | minimum: 0, G_MAXINT, default_value: 0, |
558 | flags: G_PARAM_READWRITE| |
559 | G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB)); |
560 | |
561 | /** |
562 | * GMountOperation:is-tcrypt-hidden-volume: |
563 | * |
564 | * Whether the device to be unlocked is a TCRYPT hidden volume. |
565 | * See [the VeraCrypt documentation](https://www.veracrypt.fr/en/Hidden%20Volume.html). |
566 | * |
567 | * Since: 2.58 |
568 | */ |
569 | g_object_class_install_property (oclass: object_class, |
570 | property_id: PROP_IS_TCRYPT_HIDDEN_VOLUME, |
571 | pspec: g_param_spec_boolean (name: "is-tcrypt-hidden-volume" , |
572 | P_("TCRYPT Hidden Volume" ), |
573 | P_("Whether to unlock a TCRYPT hidden volume. See https://www.veracrypt.fr/en/Hidden%20Volume.html." ), |
574 | FALSE, |
575 | flags: G_PARAM_READWRITE| |
576 | G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB)); |
577 | |
578 | /** |
579 | * GMountOperation:is-tcrypt-system-volume: |
580 | * |
581 | * Whether the device to be unlocked is a TCRYPT system volume. |
582 | * In this context, a system volume is a volume with a bootloader |
583 | * and operating system installed. This is only supported for Windows |
584 | * operating systems. For further documentation, see |
585 | * [the VeraCrypt documentation](https://www.veracrypt.fr/en/System%20Encryption.html). |
586 | * |
587 | * Since: 2.58 |
588 | */ |
589 | g_object_class_install_property (oclass: object_class, |
590 | property_id: PROP_IS_TCRYPT_SYSTEM_VOLUME, |
591 | pspec: g_param_spec_boolean (name: "is-tcrypt-system-volume" , |
592 | P_("TCRYPT System Volume" ), |
593 | P_("Whether to unlock a TCRYPT system volume. Only supported for unlocking Windows system volumes. See https://www.veracrypt.fr/en/System%20Encryption.html." ), |
594 | FALSE, |
595 | flags: G_PARAM_READWRITE| |
596 | G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB)); |
597 | |
598 | /** |
599 | * GMountOperation:pim: |
600 | * |
601 | * The VeraCrypt PIM value, when unlocking a VeraCrypt volume. See |
602 | * [the VeraCrypt documentation](https://www.veracrypt.fr/en/Personal%20Iterations%20Multiplier%20(PIM).html). |
603 | * |
604 | * Since: 2.58 |
605 | */ |
606 | g_object_class_install_property (oclass: object_class, |
607 | property_id: PROP_PIM, |
608 | pspec: g_param_spec_uint (name: "pim" , |
609 | P_("PIM" ), |
610 | P_("The VeraCrypt PIM value" ), |
611 | minimum: 0, G_MAXUINT, default_value: 0, |
612 | flags: G_PARAM_READWRITE| |
613 | G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB)); |
614 | } |
615 | |
616 | static void |
617 | g_mount_operation_init (GMountOperation *operation) |
618 | { |
619 | operation->priv = g_mount_operation_get_instance_private (self: operation); |
620 | } |
621 | |
622 | /** |
623 | * g_mount_operation_new: |
624 | * |
625 | * Creates a new mount operation. |
626 | * |
627 | * Returns: a #GMountOperation. |
628 | **/ |
629 | GMountOperation * |
630 | g_mount_operation_new (void) |
631 | { |
632 | return g_object_new (G_TYPE_MOUNT_OPERATION, NULL); |
633 | } |
634 | |
635 | /** |
636 | * g_mount_operation_get_username: |
637 | * @op: a #GMountOperation. |
638 | * |
639 | * Get the user name from the mount operation. |
640 | * |
641 | * Returns: (nullable): a string containing the user name. |
642 | **/ |
643 | const char * |
644 | g_mount_operation_get_username (GMountOperation *op) |
645 | { |
646 | g_return_val_if_fail (G_IS_MOUNT_OPERATION (op), NULL); |
647 | return op->priv->user; |
648 | } |
649 | |
650 | /** |
651 | * g_mount_operation_set_username: |
652 | * @op: a #GMountOperation. |
653 | * @username: (nullable): input username. |
654 | * |
655 | * Sets the user name within @op to @username. |
656 | **/ |
657 | void |
658 | g_mount_operation_set_username (GMountOperation *op, |
659 | const char *username) |
660 | { |
661 | g_return_if_fail (G_IS_MOUNT_OPERATION (op)); |
662 | g_free (mem: op->priv->user); |
663 | op->priv->user = g_strdup (str: username); |
664 | g_object_notify (G_OBJECT (op), property_name: "username" ); |
665 | } |
666 | |
667 | /** |
668 | * g_mount_operation_get_password: |
669 | * @op: a #GMountOperation. |
670 | * |
671 | * Gets a password from the mount operation. |
672 | * |
673 | * Returns: (nullable): a string containing the password within @op. |
674 | **/ |
675 | const char * |
676 | g_mount_operation_get_password (GMountOperation *op) |
677 | { |
678 | g_return_val_if_fail (G_IS_MOUNT_OPERATION (op), NULL); |
679 | return op->priv->password; |
680 | } |
681 | |
682 | /** |
683 | * g_mount_operation_set_password: |
684 | * @op: a #GMountOperation. |
685 | * @password: (nullable): password to set. |
686 | * |
687 | * Sets the mount operation's password to @password. |
688 | * |
689 | **/ |
690 | void |
691 | g_mount_operation_set_password (GMountOperation *op, |
692 | const char *password) |
693 | { |
694 | g_return_if_fail (G_IS_MOUNT_OPERATION (op)); |
695 | g_free (mem: op->priv->password); |
696 | op->priv->password = g_strdup (str: password); |
697 | g_object_notify (G_OBJECT (op), property_name: "password" ); |
698 | } |
699 | |
700 | /** |
701 | * g_mount_operation_get_anonymous: |
702 | * @op: a #GMountOperation. |
703 | * |
704 | * Check to see whether the mount operation is being used |
705 | * for an anonymous user. |
706 | * |
707 | * Returns: %TRUE if mount operation is anonymous. |
708 | **/ |
709 | gboolean |
710 | g_mount_operation_get_anonymous (GMountOperation *op) |
711 | { |
712 | g_return_val_if_fail (G_IS_MOUNT_OPERATION (op), FALSE); |
713 | return op->priv->anonymous; |
714 | } |
715 | |
716 | /** |
717 | * g_mount_operation_set_anonymous: |
718 | * @op: a #GMountOperation. |
719 | * @anonymous: boolean value. |
720 | * |
721 | * Sets the mount operation to use an anonymous user if @anonymous is %TRUE. |
722 | **/ |
723 | void |
724 | g_mount_operation_set_anonymous (GMountOperation *op, |
725 | gboolean anonymous) |
726 | { |
727 | GMountOperationPrivate *priv; |
728 | g_return_if_fail (G_IS_MOUNT_OPERATION (op)); |
729 | priv = op->priv; |
730 | |
731 | if (priv->anonymous != anonymous) |
732 | { |
733 | priv->anonymous = anonymous; |
734 | g_object_notify (G_OBJECT (op), property_name: "anonymous" ); |
735 | } |
736 | } |
737 | |
738 | /** |
739 | * g_mount_operation_get_domain: |
740 | * @op: a #GMountOperation. |
741 | * |
742 | * Gets the domain of the mount operation. |
743 | * |
744 | * Returns: (nullable): a string set to the domain. |
745 | **/ |
746 | const char * |
747 | g_mount_operation_get_domain (GMountOperation *op) |
748 | { |
749 | g_return_val_if_fail (G_IS_MOUNT_OPERATION (op), NULL); |
750 | return op->priv->domain; |
751 | } |
752 | |
753 | /** |
754 | * g_mount_operation_set_domain: |
755 | * @op: a #GMountOperation. |
756 | * @domain: (nullable): the domain to set. |
757 | * |
758 | * Sets the mount operation's domain. |
759 | **/ |
760 | void |
761 | g_mount_operation_set_domain (GMountOperation *op, |
762 | const char *domain) |
763 | { |
764 | g_return_if_fail (G_IS_MOUNT_OPERATION (op)); |
765 | g_free (mem: op->priv->domain); |
766 | op->priv->domain = g_strdup (str: domain); |
767 | g_object_notify (G_OBJECT (op), property_name: "domain" ); |
768 | } |
769 | |
770 | /** |
771 | * g_mount_operation_get_password_save: |
772 | * @op: a #GMountOperation. |
773 | * |
774 | * Gets the state of saving passwords for the mount operation. |
775 | * |
776 | * Returns: a #GPasswordSave flag. |
777 | **/ |
778 | |
779 | GPasswordSave |
780 | g_mount_operation_get_password_save (GMountOperation *op) |
781 | { |
782 | g_return_val_if_fail (G_IS_MOUNT_OPERATION (op), G_PASSWORD_SAVE_NEVER); |
783 | return op->priv->password_save; |
784 | } |
785 | |
786 | /** |
787 | * g_mount_operation_set_password_save: |
788 | * @op: a #GMountOperation. |
789 | * @save: a set of #GPasswordSave flags. |
790 | * |
791 | * Sets the state of saving passwords for the mount operation. |
792 | * |
793 | **/ |
794 | void |
795 | g_mount_operation_set_password_save (GMountOperation *op, |
796 | GPasswordSave save) |
797 | { |
798 | GMountOperationPrivate *priv; |
799 | g_return_if_fail (G_IS_MOUNT_OPERATION (op)); |
800 | priv = op->priv; |
801 | |
802 | if (priv->password_save != save) |
803 | { |
804 | priv->password_save = save; |
805 | g_object_notify (G_OBJECT (op), property_name: "password-save" ); |
806 | } |
807 | } |
808 | |
809 | /** |
810 | * g_mount_operation_get_choice: |
811 | * @op: a #GMountOperation. |
812 | * |
813 | * Gets a choice from the mount operation. |
814 | * |
815 | * Returns: an integer containing an index of the user's choice from |
816 | * the choice's list, or `0`. |
817 | **/ |
818 | int |
819 | g_mount_operation_get_choice (GMountOperation *op) |
820 | { |
821 | g_return_val_if_fail (G_IS_MOUNT_OPERATION (op), 0); |
822 | return op->priv->choice; |
823 | } |
824 | |
825 | /** |
826 | * g_mount_operation_set_choice: |
827 | * @op: a #GMountOperation. |
828 | * @choice: an integer. |
829 | * |
830 | * Sets a default choice for the mount operation. |
831 | **/ |
832 | void |
833 | g_mount_operation_set_choice (GMountOperation *op, |
834 | int choice) |
835 | { |
836 | GMountOperationPrivate *priv; |
837 | g_return_if_fail (G_IS_MOUNT_OPERATION (op)); |
838 | priv = op->priv; |
839 | if (priv->choice != choice) |
840 | { |
841 | priv->choice = choice; |
842 | g_object_notify (G_OBJECT (op), property_name: "choice" ); |
843 | } |
844 | } |
845 | |
846 | /** |
847 | * g_mount_operation_get_is_tcrypt_hidden_volume: |
848 | * @op: a #GMountOperation. |
849 | * |
850 | * Check to see whether the mount operation is being used |
851 | * for a TCRYPT hidden volume. |
852 | * |
853 | * Returns: %TRUE if mount operation is for hidden volume. |
854 | * |
855 | * Since: 2.58 |
856 | **/ |
857 | gboolean |
858 | g_mount_operation_get_is_tcrypt_hidden_volume (GMountOperation *op) |
859 | { |
860 | g_return_val_if_fail (G_IS_MOUNT_OPERATION (op), FALSE); |
861 | return op->priv->hidden_volume; |
862 | } |
863 | |
864 | /** |
865 | * g_mount_operation_set_is_tcrypt_hidden_volume: |
866 | * @op: a #GMountOperation. |
867 | * @hidden_volume: boolean value. |
868 | * |
869 | * Sets the mount operation to use a hidden volume if @hidden_volume is %TRUE. |
870 | * |
871 | * Since: 2.58 |
872 | **/ |
873 | void |
874 | g_mount_operation_set_is_tcrypt_hidden_volume (GMountOperation *op, |
875 | gboolean hidden_volume) |
876 | { |
877 | GMountOperationPrivate *priv; |
878 | g_return_if_fail (G_IS_MOUNT_OPERATION (op)); |
879 | priv = op->priv; |
880 | |
881 | if (priv->hidden_volume != hidden_volume) |
882 | { |
883 | priv->hidden_volume = hidden_volume; |
884 | g_object_notify (G_OBJECT (op), property_name: "is-tcrypt-hidden-volume" ); |
885 | } |
886 | } |
887 | |
888 | /** |
889 | * g_mount_operation_get_is_tcrypt_system_volume: |
890 | * @op: a #GMountOperation. |
891 | * |
892 | * Check to see whether the mount operation is being used |
893 | * for a TCRYPT system volume. |
894 | * |
895 | * Returns: %TRUE if mount operation is for system volume. |
896 | * |
897 | * Since: 2.58 |
898 | **/ |
899 | gboolean |
900 | g_mount_operation_get_is_tcrypt_system_volume (GMountOperation *op) |
901 | { |
902 | g_return_val_if_fail (G_IS_MOUNT_OPERATION (op), FALSE); |
903 | return op->priv->system_volume; |
904 | } |
905 | |
906 | /** |
907 | * g_mount_operation_set_is_tcrypt_system_volume: |
908 | * @op: a #GMountOperation. |
909 | * @system_volume: boolean value. |
910 | * |
911 | * Sets the mount operation to use a system volume if @system_volume is %TRUE. |
912 | * |
913 | * Since: 2.58 |
914 | **/ |
915 | void |
916 | g_mount_operation_set_is_tcrypt_system_volume (GMountOperation *op, |
917 | gboolean system_volume) |
918 | { |
919 | GMountOperationPrivate *priv; |
920 | g_return_if_fail (G_IS_MOUNT_OPERATION (op)); |
921 | priv = op->priv; |
922 | |
923 | if (priv->system_volume != system_volume) |
924 | { |
925 | priv->system_volume = system_volume; |
926 | g_object_notify (G_OBJECT (op), property_name: "is-tcrypt-system-volume" ); |
927 | } |
928 | } |
929 | |
930 | /** |
931 | * g_mount_operation_get_pim: |
932 | * @op: a #GMountOperation. |
933 | * |
934 | * Gets a PIM from the mount operation. |
935 | * |
936 | * Returns: The VeraCrypt PIM within @op. |
937 | * |
938 | * Since: 2.58 |
939 | **/ |
940 | guint |
941 | g_mount_operation_get_pim (GMountOperation *op) |
942 | { |
943 | g_return_val_if_fail (G_IS_MOUNT_OPERATION (op), 0); |
944 | return op->priv->pim; |
945 | } |
946 | |
947 | /** |
948 | * g_mount_operation_set_pim: |
949 | * @op: a #GMountOperation. |
950 | * @pim: an unsigned integer. |
951 | * |
952 | * Sets the mount operation's PIM to @pim. |
953 | * |
954 | * Since: 2.58 |
955 | **/ |
956 | void |
957 | g_mount_operation_set_pim (GMountOperation *op, |
958 | guint pim) |
959 | { |
960 | GMountOperationPrivate *priv; |
961 | g_return_if_fail (G_IS_MOUNT_OPERATION (op)); |
962 | priv = op->priv; |
963 | if (priv->pim != pim) |
964 | { |
965 | priv->pim = pim; |
966 | g_object_notify (G_OBJECT (op), property_name: "pim" ); |
967 | } |
968 | } |
969 | |
970 | /** |
971 | * g_mount_operation_reply: |
972 | * @op: a #GMountOperation |
973 | * @result: a #GMountOperationResult |
974 | * |
975 | * Emits the #GMountOperation::reply signal. |
976 | **/ |
977 | void |
978 | g_mount_operation_reply (GMountOperation *op, |
979 | GMountOperationResult result) |
980 | { |
981 | g_return_if_fail (G_IS_MOUNT_OPERATION (op)); |
982 | g_signal_emit (instance: op, signal_id: signals[REPLY], detail: 0, result); |
983 | } |
984 | |