196
server_side_source_allow_auth_prompt_cb (EDBusSource *dbus_interface,
197
GDBusMethodInvocation *invocation,
198
EServerSideSource *source)
200
e_server_side_source_set_allow_auth_prompt (source, TRUE);
202
e_dbus_source_complete_allow_auth_prompt (dbus_interface, invocation);
203
static ESourceCredentialsReason
204
server_side_source_credentials_reason_from_text (const gchar *arg_reason)
206
ESourceCredentialsReason reason = E_SOURCE_CREDENTIALS_REASON_UNKNOWN;
208
if (arg_reason && *arg_reason) {
209
GEnumClass *enum_class;
210
GEnumValue *enum_value;
212
enum_class = g_type_class_ref (E_TYPE_SOURCE_CREDENTIALS_REASON);
213
enum_value = g_enum_get_value_by_nick (enum_class, arg_reason);
216
reason = enum_value->value;
218
g_warning ("%s: Unknown reason enum: '%s'", G_STRFUNC, arg_reason);
221
g_type_class_unref (enum_class);
227
typedef struct _ReinvokeCredentialsRequiredData {
228
EServerSideSource *source;
230
gchar *arg_certificate_pem;
231
gchar *arg_certificate_errors;
232
gchar *arg_dbus_error_name;
233
gchar *arg_dbus_error_message;
234
} ReinvokeCredentialsRequiredData;
237
reinvoke_credentials_required_data_free (gpointer ptr)
239
ReinvokeCredentialsRequiredData *data = ptr;
242
g_clear_object (&data->source);
243
g_free (data->arg_reason);
244
g_free (data->arg_certificate_pem);
245
g_free (data->arg_certificate_errors);
246
g_free (data->arg_dbus_error_name);
247
g_free (data->arg_dbus_error_message);
252
static void server_side_source_credentials_lookup_cb (GObject *source_object, GAsyncResult *result, gpointer user_data);
255
server_side_source_invoke_credentials_required_cb (EDBusSource *dbus_interface,
256
GDBusMethodInvocation *invocation,
257
const gchar *arg_reason,
258
const gchar *arg_certificate_pem,
259
const gchar *arg_certificate_errors,
260
const gchar *arg_dbus_error_name,
261
const gchar *arg_dbus_error_message,
262
EServerSideSource *source)
264
gboolean skip_emit = FALSE;
267
e_dbus_source_complete_invoke_credentials_required (dbus_interface, invocation);
269
g_mutex_lock (&source->priv->pending_credentials_lookup_lock);
270
if (source->priv->pending_credentials_lookup) {
271
g_cancellable_cancel (source->priv->pending_credentials_lookup);
272
g_clear_object (&source->priv->pending_credentials_lookup);
274
g_mutex_unlock (&source->priv->pending_credentials_lookup_lock);
276
g_mutex_lock (&source->priv->last_values_lock);
278
g_free (source->priv->last_reason);
279
g_free (source->priv->last_certificate_pem);
280
g_free (source->priv->last_certificate_errors);
281
g_free (source->priv->last_dbus_error_name);
282
g_free (source->priv->last_dbus_error_message);
283
source->priv->last_reason = g_strdup (arg_reason);
284
source->priv->last_certificate_pem = g_strdup (arg_certificate_pem);
285
source->priv->last_certificate_errors = g_strdup (arg_certificate_errors);
286
source->priv->last_dbus_error_name = g_strdup (arg_dbus_error_name);
287
source->priv->last_dbus_error_message = g_strdup (arg_dbus_error_message);
289
g_mutex_unlock (&source->priv->last_values_lock);
291
/* Do not bother clients, when the password is stored. */
292
if (server_side_source_credentials_reason_from_text (arg_reason) == E_SOURCE_CREDENTIALS_REASON_REQUIRED) {
293
ESourceRegistryServer *server;
294
ESourceCredentialsProvider *credentials_provider;
296
server = e_server_side_source_get_server (source);
297
credentials_provider = server ? e_source_registry_server_ref_credentials_provider (server) : NULL;
299
if (credentials_provider) {
300
ReinvokeCredentialsRequiredData *data;
301
GCancellable *cancellable;
303
g_mutex_lock (&source->priv->pending_credentials_lookup_lock);
304
if (source->priv->pending_credentials_lookup) {
305
g_cancellable_cancel (source->priv->pending_credentials_lookup);
306
g_clear_object (&source->priv->pending_credentials_lookup);
308
cancellable = g_cancellable_new ();
309
source->priv->pending_credentials_lookup = g_object_ref (cancellable);
310
g_mutex_unlock (&source->priv->pending_credentials_lookup_lock);
312
data = g_new0 (ReinvokeCredentialsRequiredData, 1);
313
data->source = g_object_ref (source);
314
data->arg_reason = g_strdup (arg_reason);
315
data->arg_certificate_pem = g_strdup (arg_certificate_pem);
316
data->arg_certificate_errors = g_strdup (arg_certificate_errors);
317
data->arg_dbus_error_name = g_strdup (arg_dbus_error_name);
318
data->arg_dbus_error_message = g_strdup (arg_dbus_error_message);
322
e_source_credentials_provider_lookup (credentials_provider, E_SOURCE (source),
323
cancellable, server_side_source_credentials_lookup_cb, data);
325
g_object_unref (cancellable);
328
g_clear_object (&credentials_provider);
332
e_dbus_source_emit_credentials_required (dbus_interface, arg_reason, arg_certificate_pem, arg_certificate_errors, arg_dbus_error_name, arg_dbus_error_message);
339
server_side_source_invoke_authenticate_cb (EDBusSource *dbus_interface,
340
GDBusMethodInvocation *invocation,
341
const gchar * const *arg_credentials,
342
EServerSideSource *source)
344
gchar **last_credentials_strv = NULL;
346
g_return_val_if_fail (E_IS_SERVER_SIDE_SOURCE (source), TRUE);
348
g_mutex_lock (&source->priv->pending_credentials_lookup_lock);
349
if (source->priv->pending_credentials_lookup) {
350
g_cancellable_cancel (source->priv->pending_credentials_lookup);
351
g_clear_object (&source->priv->pending_credentials_lookup);
353
g_mutex_unlock (&source->priv->pending_credentials_lookup_lock);
355
g_mutex_lock (&source->priv->last_values_lock);
357
/* Empty credentials are used to use the last credentials instead */
358
if (source->priv->last_credentials && arg_credentials && !arg_credentials[0]) {
359
last_credentials_strv = e_named_parameters_to_strv (source->priv->last_credentials);
360
arg_credentials = (const gchar * const *) last_credentials_strv;
361
} else if (arg_credentials && arg_credentials[0]) {
362
ENamedParameters *credentials = e_named_parameters_new_strv (arg_credentials);
364
/* If only one credential value is passed in, and it's the SSL Trust,
365
and there was any credentials already tried, then merge the previous
366
credentials with the SSL Trust, to inherit the password, if any. */
367
if (source->priv->last_credentials &&
368
e_named_parameters_count (credentials) == 1 &&
369
e_named_parameters_exists (credentials, E_SOURCE_CREDENTIAL_SSL_TRUST)) {
372
count = e_named_parameters_count (source->priv->last_credentials);
373
for (ii = 0; ii < count; ii++) {
376
name = e_named_parameters_get_name (source->priv->last_credentials, ii);
380
if (*name && !e_named_parameters_exists (credentials, name)) {
381
e_named_parameters_set (credentials, name,
382
e_named_parameters_get (source->priv->last_credentials, name));
388
last_credentials_strv = e_named_parameters_to_strv (credentials);
389
arg_credentials = (const gchar * const *) last_credentials_strv;
392
e_named_parameters_free (source->priv->last_credentials);
393
source->priv->last_credentials = credentials;
396
g_free (source->priv->last_reason);
397
g_free (source->priv->last_certificate_pem);
398
g_free (source->priv->last_certificate_errors);
399
g_free (source->priv->last_dbus_error_name);
400
g_free (source->priv->last_dbus_error_message);
401
source->priv->last_reason = NULL;
402
source->priv->last_certificate_pem = NULL;
403
source->priv->last_certificate_errors = NULL;
404
source->priv->last_dbus_error_name = NULL;
405
source->priv->last_dbus_error_message = NULL;
407
g_mutex_unlock (&source->priv->last_values_lock);
410
e_dbus_source_complete_invoke_authenticate (dbus_interface, invocation);
412
e_dbus_source_emit_authenticate (dbus_interface, arg_credentials);
414
g_strfreev (last_credentials_strv);
420
server_side_source_credentials_lookup_cb (GObject *source_object,
421
GAsyncResult *result,
424
GDBusObject *dbus_object;
425
EDBusSource *dbus_source;
426
ReinvokeCredentialsRequiredData *data = user_data;
427
ENamedParameters *credentials = NULL;
429
GError *error = NULL;
431
g_return_if_fail (E_IS_SOURCE_CREDENTIALS_PROVIDER (source_object));
432
g_return_if_fail (data != NULL);
434
success = e_source_credentials_provider_lookup_finish (E_SOURCE_CREDENTIALS_PROVIDER (source_object), result, &credentials, &error);
436
dbus_object = e_source_ref_dbus_object (E_SOURCE (data->source));
438
e_named_parameters_free (credentials);
439
reinvoke_credentials_required_data_free (data);
443
dbus_source = e_dbus_object_get_source (E_DBUS_OBJECT (dbus_object));
445
e_named_parameters_free (credentials);
446
g_clear_object (&dbus_object);
447
reinvoke_credentials_required_data_free (data);
451
if (success && credentials) {
452
gchar **arg_credentials;
454
arg_credentials = e_named_parameters_to_strv (credentials);
456
server_side_source_invoke_authenticate_cb (dbus_source, NULL,
457
(const gchar * const *) arg_credentials, data->source);
459
g_strfreev (arg_credentials);
460
} else if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
462
printf ("%s: Failed to lookup password: %s\n", G_STRFUNC, error ? error->message : "Unknown error");
466
if (server_side_source_credentials_reason_from_text (data->arg_reason) == E_SOURCE_CREDENTIALS_REASON_REQUIRED &&
467
error && !e_source_credentials_provider_can_prompt (E_SOURCE_CREDENTIALS_PROVIDER (source_object), E_SOURCE (data->source))) {
468
GEnumClass *enum_class;
469
GEnumValue *enum_value;
470
gchar *dbus_error_name;
472
enum_class = g_type_class_ref (E_TYPE_SOURCE_CREDENTIALS_REASON);
473
enum_value = g_enum_get_value (enum_class, E_SOURCE_CREDENTIALS_REASON_ERROR);
475
g_return_if_fail (enum_value != NULL);
477
dbus_error_name = g_dbus_error_encode_gerror (error);
479
/* Use error reason when the source cannot be prompted for credentials */
480
e_dbus_source_emit_credentials_required (dbus_source, enum_value->value_nick,
481
data->arg_certificate_pem, data->arg_certificate_errors, dbus_error_name, error->message);
483
g_type_class_unref (enum_class);
484
g_free (dbus_error_name);
486
/* Reinvoke for clients only, if not cancelled */
487
const gchar *arg_dbus_error_name, *arg_dbus_error_message;
488
gchar *dbus_error_name = NULL;
490
arg_dbus_error_name = data->arg_dbus_error_name;
491
arg_dbus_error_message = data->arg_dbus_error_message;
493
if (!arg_dbus_error_name || !*arg_dbus_error_name) {
495
error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_FAILED, _("Unknown error"));
497
dbus_error_name = g_dbus_error_encode_gerror (error);
498
arg_dbus_error_name = dbus_error_name;
499
arg_dbus_error_message = error->message;
502
e_dbus_source_emit_credentials_required (dbus_source, data->arg_reason,
503
data->arg_certificate_pem, data->arg_certificate_errors,
504
arg_dbus_error_name, arg_dbus_error_message);
506
g_free (dbus_error_name);
510
e_named_parameters_free (credentials);
511
reinvoke_credentials_required_data_free (data);
512
g_object_unref (dbus_source);
513
g_object_unref (dbus_object);
514
g_clear_error (&error);
518
server_side_source_get_last_credentials_required_arguments_cb (EDBusSource *dbus_interface,
519
GDBusMethodInvocation *invocation,
520
EServerSideSource *source)
522
g_mutex_lock (&source->priv->last_values_lock);
524
e_dbus_source_complete_get_last_credentials_required_arguments (dbus_interface, invocation,
525
source->priv->last_reason ? source->priv->last_reason : "",
526
source->priv->last_certificate_pem ? source->priv->last_certificate_pem : "",
527
source->priv->last_certificate_errors ? source->priv->last_certificate_errors : "",
528
source->priv->last_dbus_error_name ? source->priv->last_dbus_error_name : "",
529
source->priv->last_dbus_error_message ? source->priv->last_dbus_error_message : "");
531
g_mutex_unlock (&source->priv->last_values_lock);
1713
* e_server_side_source_get_allow_auth_prompt:
1714
* @source: an #EServerSideSource
1716
* Returns whether an authentication prompt is allowed to be shown
1717
* for @source. #EAuthenticationSession will honor this setting by
1718
* dismissing the session if it can't find a valid stored password.
1720
* See e_server_side_source_set_allow_auth_prompt() for further
1723
* Returns: whether auth prompts are allowed for @source
1728
e_server_side_source_get_allow_auth_prompt (EServerSideSource *source)
1730
g_return_val_if_fail (E_IS_SERVER_SIDE_SOURCE (source), FALSE);
1732
return source->priv->allow_auth_prompt;
1736
* e_server_side_source_set_allow_auth_prompt:
1737
* @source: an #EServerSideSource
1738
* @allow_auth_prompt: whether auth prompts are allowed for @source
1740
* Sets whether an authentication prompt is allowed to be shown for @source.
1741
* #EAuthenticationSession will honor this setting by dismissing the session
1742
* if it can't find a valid stored password.
1744
* If the user declines to provide a password for @source when prompted
1745
* by an #EAuthenticationSession, the #ESourceRegistryServer will set this
1746
* property to %FALSE to suppress any further prompting, which would likely
1747
* annoy the user. However when an #ESourceRegistry instance is created by
1748
* a client application, the first thing it does is reset this property to
1749
* %TRUE for all registered data sources. So suppressing authentication
1750
* prompts is only ever temporary.
1755
e_server_side_source_set_allow_auth_prompt (EServerSideSource *source,
1756
gboolean allow_auth_prompt)
1758
g_return_if_fail (E_IS_SERVER_SIDE_SOURCE (source));
1760
if (source->priv->allow_auth_prompt == allow_auth_prompt)
1763
source->priv->allow_auth_prompt = allow_auth_prompt;
1765
g_object_notify (G_OBJECT (source), "allow-auth-prompt");
1769
* e_server_side_source_get_auth_session_type:
1770
* @source: an #EServerSideSource
1772
* Returns the type of authentication session to use for @source,
1773
* which will get passed to e_source_registry_server_authenticate().
1775
* This defaults to the #GType for #EAuthenticationSession.
1777
* Returns: the type of authentication session to use for @source
1782
e_server_side_source_get_auth_session_type (EServerSideSource *source)
1784
g_return_val_if_fail (
1785
E_IS_SERVER_SIDE_SOURCE (source),
1786
E_TYPE_AUTHENTICATION_SESSION);
1788
return source->priv->auth_session_type;
1792
* e_server_side_source_set_auth_session_type:
1793
* @source: an #EServerSideSource
1794
* @auth_session_type: the type of authentication session to use for @source
1796
* Sets the type of authentication session to use for @source, which will
1797
* get passed to e_source_registry_server_authenticate().
1799
* @auth_session_type must be derived from #EAuthenticationSession, or else
1800
* the function will reject the #GType with a runtime warning.
1802
* This defaults to the #GType for #EAuthenticationSession.
1807
e_server_side_source_set_auth_session_type (EServerSideSource *source,
1808
GType auth_session_type)
1810
g_return_if_fail (E_IS_SERVER_SIDE_SOURCE (source));
1812
if (!g_type_is_a (auth_session_type, E_TYPE_AUTHENTICATION_SESSION)) {
1814
"Invalid auth session type '%s' for source '%s'",
1815
g_type_name (auth_session_type),
1816
e_source_get_display_name (E_SOURCE (source)));
1820
if (auth_session_type == source->priv->auth_session_type)
1823
source->priv->auth_session_type = auth_session_type;
1825
g_object_notify (G_OBJECT (source), "auth-session-type");
1829
2058
* e_server_side_source_get_exported:
1830
2059
* @source: an #EServerSideSource